glance-2014.1/0000775000175400017540000000000012323736427014201 5ustar jenkinsjenkins00000000000000glance-2014.1/HACKING.rst0000664000175400017540000000035212323736226015774 0ustar jenkinsjenkins00000000000000glance Style Commandments ======================= - Step 1: Read the OpenStack Style Commandments http://docs.openstack.org/developer/hacking/ - Step 2: Read on glance Specific Commandments -------------------------- None so far glance-2014.1/.mailmap0000664000175400017540000000226712323736226015626 0ustar jenkinsjenkins00000000000000# Format is: # # Zhongyue Luo Zhenguo Niu David Koo glance-2014.1/test-requirements.txt0000664000175400017540000000076712323736226020451 0ustar jenkinsjenkins00000000000000# Hacking already pins down pep8, pyflakes and flake8 hacking>=0.8.0,<0.9 # For translations processing Babel>=1.3 # Needed for testing coverage>=3.6 discover fixtures>=0.3.14 mox>=0.5.3 mock>=1.0 sphinx>=1.1.2,<1.2 requests>=1.1 testrepository>=0.0.18 testtools>=0.9.34 psutil>=1.1.1 # Optional packages that should be installed when testing MySQL-python psycopg2 -f http://pysendfile.googlecode.com/files/pysendfile-2.0.0.tar.gz pysendfile==2.0.0 qpid-python xattr>=0.4 # Documentation oslosphinx glance-2014.1/.coveragerc0000664000175400017540000000015412323736226016317 0ustar jenkinsjenkins00000000000000[run] branch = True source = glance omit = glance/tests/*,glance/openstack/* [report] ignore-errors = True glance-2014.1/ChangeLog0000664000175400017540000035345212323736426015766 0ustar jenkinsjenkins00000000000000CHANGES ======= 2014.1 ------ * Fixes Glance Registry V2 client * Update Glance configuration sample files for database options * To prevent remote code injection on Sheepdog store * Fix Jenkins translation jobs * Catch loading failures if transport_url is not set * Updated from global requirements 2014.1.rc1 ---------- * Making DB sanity checking be optional for DB migration * Fix swift functional test "test_create_store" * Sanitize set passed to jsonutils.dumps() * Imported Translations from Transifex * Sync common db code from Oslo * Return 405 when attempting DELETE on /tasks * Remove openstack.common.fixture * VMware store.add to return the image size uploaded * registry: log errors on failure * Removes use of timeutils.set_time_override * Make the VMware datastore backend more robust * Pass Message object to webob exception * Detect MultiDict when generating json body * Makes possible to enable Registry API v1 and v2 * Updated from global requirements * Provide an upgrade period for enabling stores * API v2: Allow GET on unowned images with show_image_direct_url * Add copyright text to glance/openstack/common/__init__.py * Don't enable all stores by default * Fix glance db migration failed on 031 * Document for API message localization 2014.1.b3 --------- * Add support for API message localization * Add the OVA container format * Store URI must start with the expected URI scheme * Documentation for Glance tasks * Remove import specific validation from tasks resource * Remove dependency of test_v1_api on other tests * Include Location header in POST /tasks response * Catch exception when image cache pruning * VMware storage backend should use oslo.vmware * Sync common db code from Oslo * Refactor UUID test * Replaced calls of get(foo, None) -> get(foo) * Use six.StringIO/BytesIO instead of StringIO.StringIO * Replaced "...\'%s\'..." with "...'%s'..." * Updated from global requirements * Fix logging context to include user_identity * Log 'image_id' with all BadStoreURI error messages * Added undescore function to some strings * Use 0-based indices for location entries * Glance all: Replace basestring by six for python3 compatability * Delete image metadata after image is deleted * Modify assert statement when comparing with None * Enable hacking H301 and disable H304, H302 * Replacement mox by mock * Keep py3.X compatibility for urllib * Use uuid instead of uuidutils * Use six.moves.urllib.parse instead of urlparse * Switch over to oslosphinx * Fix parsing of AMQP configuration * Add `virtual_size` to Glance's API v2 * Add a virtual_size attribute to the Image model * Enable F841 check * Add support for PartialTask list * Rename Openstack to OpenStack * Add a mailmap entry for myself * Sync log.py from oslo * Add unit tests around glance-manage * Remove tox locale overrides * Improve help strings * Provide explicit image create value in Registry v2 API test * Adding status field to image location -- DB migration * Apply image location selection strategy * Switch to testrepository for running tests * Clean up DatabaseMigrationError * Enable H302 check * Fix misspellings in glance * Expose image property 'owner' in v2 API * Removes logging of location uri * Updated from global requirements * Remove duplicate type defination of v2 images schema * Enable H202 check * Modify my mailmap * glance-manage wont take version into consideration * Move scrubber outside the store package * Depending on python-swiftclient>=1.6 * Now psutil>=1.1.0 is actually on PyPI * Fix indentation errors found by Pep8 1.4.6+ * Add VMware storage backend to location strategy * Log a warning when a create fails due to quota * glance requires pyOpenSSL>=0.11 * Imported Translations from Transifex * VMware Datastore storage backend * Restore image status to 'queued' if upload failed * Don't override transport_url with old configs * Provide explicit image create value in Registry v2 Client test * Provide explicit task create and update value in controller tests * Enable hacking H703 check * Sync with global requirements * Sync oslo.messaging version with global-requirements * Don't rewrite the NotFound error message * Update all the glance manpages * Use common db migrations module from Oslo * Check --store parameter validity before _reserve * Sync gettextutils from Oslo * Enable gating on H501 * Add multifilesystem store to support NFS servers as backend * Check first matching rule for protected properties * Retry failed image download from Swift * Restore image status on duplicate image upload 2014.1.b2 --------- * Tests added for glance/cmd/cache_pruner.py * Prevent E500 when delayed delete is enabled * Sync unhandled exception logging change from Oslo * Check image id format before executing operations * fix bug:range() is not same in py3.x and py2.x * Fix the incorrect log message when creating images * Adding image location selection strategies * Fix inconsistent doc string and code of db_sync * fixing typo in rst file * Fix tmp DB path calculation for test_migrations.py * Change assertTrue(isinstance()) by optimal assert * add log for _get_images method * Makes 'expires_at' not appear if not set on task * Remove vim header * Update the glance-api manpage * Remove 'openstack/common/context.py' * Allow users to customize max header size * Decouple the config dependence on glance domain * Fix typo in doc string * Prevent min_disk and min_ram from being negative * Set image size to None after removing all locations * Update README to the valid Oslo-incubator doc * Cleans up imports in models.py * Sync Log levels from OSLO * Align glance-api.conf rbd option defaults with config * Bump hacking to 0.8 and get python 3.x compatibility * Add config option to limit image locations * replace type calls with isinstance * Adding logs to tasks * Skip unconfigurable drivers for store initialization * Fix typo in gridfs store * Oslo sync to recover from db2 server disconnects * fix comments and docstrings misspelled words * Fix call to store.safe_delete_from_backend * Switch to Hacking 0.8.x * assertEquals is deprecated, use assertEqual (H234) * Consider @,! in properties protection rule as a configuration error * Remove unused imports in glance * Remove return stmt of add,save and remove method * Migrate json to glance.openstack.common.jsonutils * Use common Oslo database session * Define sheepdog_port as an integer value * Sync with oslo-incubator (git 6827012) * Enable gating on F811 (duplicate function definition) * Set image size after updating/adding locations * Disallow negative image sizes * Fix and enable gating on H306 * Make code base E125 and E126 compliant * Fix 031 migration failed on DB2 * Remove the redundant code * Correct URL in v1 test_get_images_unauthorized * Refactor tests.unit.utils:FakeDB.reset * Fixed wrong string format in glance.api.v2.image_data * Empty files shouldn't contain copyright nor license * Use uuid instead of uuidutils * Enable H233/H301/H302 tests that are ignored at the moment * Remove duplicate method implementations in ImageLocationsProxy * Make Glance code base H102 compliant * Make Glance code base H201 compliant * Cleanup: remove unused code from store_utils * Filter out deleted images from storage usage * Add db2 communication error code when check the db connection * Refine output of glance service managment * Adds guard against upload contention * Fixes HTTP 500 when updating image with locations for V2 * Increase test coverage for glance.common.wsgi * Return 204 when image data does not exist * V2: disallow image format update for active status * Enable tasks REST API for async worker * Cleanly fail when location URI is malformed * Rename duplicate test_add_copy_from_upload_image_unauthorized * Adding missing copy_from policy from policy.json * Fix simple-db image filtering on extra properties * Pin sphinx to <1.2 * assertEquals is deprecated, use assertEqual instead * Fix and enable gating on H702 * Replace startswith by more precise store matching * Remove unused exceptions * Remove duplicate method __getitem__ in quota/__init__.py * Enforce copy_from policy during image-update * Refactor StorageQuotaFull test cases in test_quota * remove hardcode of usage * Added error logging for http store * Forbidden update message diffs images/tasks/member * Unittests added for glance/cmd/cache_manage.py * Makes tasks owner not nullable in models.py * Move is_image_sharable to registry api * Remove TestRegistryDB dependency on TestRegistryAPI * Introduce Task Info Table 2014.1.b1 --------- * Migrate to oslo.messaging * Add config option to limit image members * Add config option to limit image tags * Glance image-list failed when image number exceed DEFAULT_PAGE_SIZE * DB migration changes to support DB2 as sqlalchemy backend * Add documentation for some API parameters * RBD add() now returns correct size if given zero * Set upload_image policy to control data upload * Replace deprecated method assertEquals * Clean up duplicate code in v2.image_data.py * Fix docstring on detail in glance/api/v1/images.py * Use assertEqual instead of assertEquals in unit tests * Remove unused package in requirement.txt * Enable F40X checking * Verify for duplicate location+metadata instances * Adds domain level support for tasks * Add eclipse project files to .gitignore * Added unit tests for api/middleware/cache_manage.py * Fixed quotes in _assert_tables() method * Use common db model class from Oslo * Add upload policy for glance v2 api * Adding an image status transition diagram for dev doc * Add config option to limit image properties * Explicit listing of Glance policies in json file * Imported Translations from Transifex * Sync openstack.common.local from oslo * Clean up numeric expressions with oslo constants * Don't use deprecated module commands * Add tests for glance/notifier/notify_kombu * Fixes image delete and upload contention * Log unhandled exceptions * Add tests for glance/image_cache/client.py * Remove lxml requirement * Sync common db and db.sqlalchemy code from Oslo * Update glance/opensatck/common from oslo Part 3 * Tests added for glance/cmd/cache_cleaner.py * glance-manage should work like nova-manage * Adds tasks to db api * Sync lockutils from oslo * sync log from oslo * Add policy style '@'/'!' rules to prop protections * Enable H501: do not use locals() for formatting * Remove use of locals() when creating messages * Remove "image_cache_invalid_entry_grace_period" option * Add unit test cases for get func of db member repo * assertEquals is deprecated, use assertEqual * Document default log location in config files * Remove unused method setup_logging * Start using PyFlakes and Hacking * Sync units module from olso * Fixes error message encoding issue when using qpid * Use mock in test_policy * Use packaged version of ordereddict * Imported Translations from Transifex * Glance v2: Include image/member id in 404 Response * Replace qpid_host with qpid_hostname * Fix Pep8 1.4.6 warnings * Fixes content-type checking for image uploading in API v1 and v2 * Update my mailmap * Addition of third example for Property Protections * Sync iso8601 requirement and fixes test case failures * Fixes wrong Qpid protocol configuration * Use HTTP storage to test copy file functionality * Remove redundant dependencies in test-requirements * Documentation for using policies for protected properties * checking length of argument list in "glance-cache-image" command * optimize queries for image-list * Using policies for protected properties * Cleanup and make HACKING.rst DRYer * Enable tasks data model and table for async worker * Updated from global requirements * Add call to get specific image member * Put formatting operation outside localisation call * Remove unused import * The V2 Api should delete a non existent image * Avoid printing URIs which can contain credentials * Remove whitespace from cfg options * Use Unix style LF instead of DOS style CRLF * Adding 'download_image' policy enforcement to image cache middleware * Glance manage should parse glance-api.conf * Fixes rbd _delete_image snapshot with missing image * Correct documentation related to protected properties * Update functional tests for swift changes * Removed unsued import, HTTPError in v1/images.py * Allow tests to run with both provenances of mox * Glance GET /v2/images fails with 500 due to erroneous policy check * Do not allow the same member to be added twice 2013.2.rc1 ---------- * V2 RpcApi should register when db pool is enabled * Imported Translations from Transifex * Open Icehouse development * Convert Windows to Unix style line endings * Add documentation for property protections * Adding checking to prevent conflict image size * Fixes V2 member-create allows adding an empty tenantId as member * Fixing glance-api hangs in the qpid notifier * Change response code for successful delete image member to 204 * Cache cleaner wrongly deletes cache for non invalid images * Require oslo.config 1.2.0 final * Use built-in print() instead of print statement * Swift store add should not use wildcard raise * Corrected v2 image sharing documentation * Add swift_store_ssl_compression param * Log a message when image object not found in swift * Ensure prop protections are read/enforced in order * Funtional Tests should call glance.db.get_api * Enclose command args in with_venv.sh * Fix typo in config string * Adding encryption support for image multiple locations * Fixes typos of v1 meta data in glanceapi.rst * Respond with 410 after upload if image was deleted * Fix misused assertTrue in unit tests * Convert location meta data from pickle to string * Disallow access/modify members of deleted image * Fix typo in protected property message * Remove the unused mapper of image member create * Changed header from LLC to Foundation based on trademark policies * Implement protected properties for API v1 * Add rbd store support for zero size image * Remove start index 0 in range() * Convert non-English exception message when a store loading error * add missing index for 'owner' column on images table * Publish recent api changes as v2.2 * Update schema descriptions to indicate readonly * Enable protected properties in gateway * Property Protection Layer * Rule parser for property protections * Scrubber refactoring * Fix typo in IMAGE_META_HEADERS * Fix localisation string usage * Notify error not called on upload errors in V2 * Fixes files with wrong bitmode * Remove unused local vars * Clean up data when store receiving image occurs error * Show traceback info if a functional test fails * Add a storage quota * Avoid redefinition of test * Fix useless assertTrue * emit warning while running flake8 without virtual env * Fix up trivial License mismatches * Introduced DB pooling for non blocking DB calls * Use latest Oslo's version * Improve the error msg of v2 image_data.py * Fix Sphinx warning * Remove unused import * test failure induced by reading system config file * Prefetcher should perform data integrity check * Make size/checksum immutable for active images * Remove unused var DEFAULT_MAX_CACHE_SIZE * Implement image query by tag * Remove unused import of oslo.config * Code dedup in glance/tests/unit/v1/test_registry_api.py * Add unit test for migration 012 * Call _post_downgrade_### after downgrade migration is run * Use _pre_upgrade_### instead of _prerun_### * Perform database migration snake walk test correctly * redundant conditions in paginate-query * Refactor glance/tests/unit/v2/test_registry_client.py * Refactor glance/tests/unit/v1/test_registry_client.py * Improve test/utils.py * Make sure owner column doesn't get dropped during downgrade * image-delete fires multiple queries to delete its child entries * glance-replicator: enable logging exceptions into log file * Make disk and container formats configurable * Add space in etc/glance-cache.conf * Removes duplicate options registration in registry clients * remove flake8 option in run_tests.sh * Allow tests to run without installation * Remove glance CLI man page * Fix some logic in get_caching_iter * Adding metadata checking to image location proxy layer * Update .mailmap * Migrate to PBR for setup and version code * Interpolate strings after calling _() * BaseException.message is deprecated since Python 2.6 * Raise jsonschema requirement * Text formatting changes * Using unicode() convert non-English exception message * ambiguous column 'checksum' error when querying image-list(v2) * Handle None value properties in glance-replicator * Fixes Opt types in glance/notifier/notify_kombu.py * Add unit test for migration 010 * Sync models with migrations * Rename requirements files to standard names * Include pipeline option for using identity headers * Adding arguments pre-check for glance-replicator * Add v1 API x-image-meta- header whitelist * Stub out dependency on subprocess in unit tests * Allow insecure=True to be set in swiftclient * Verify if the RPC result is an instance of dict * Adds help messages to mongodb_store_db and mongodb_store_uri * Remove support for sqlalchemy-migrate < 0.7 * Don't rely on prog.Name for paste app * Simulate image_locations table in simple/api.py * Turn off debug logging in sqlalchemy by default * Glance api to pass identity headers to registry v1 * add doc/source/api in gitignore * Use cross-platform 'ps' for test_multiprocessing * Fix stubs setup and exception message formatting * Handle client disconnect during image upload * improving error handling in chunked upload 2013.2.b2 --------- * Adding Cinder backend storage driver to Glance * File system store can send metadata back with the location * index checksum image property * removed unused variable 'registry_port' * DB Driver for the Registry Service * Unit tests for scrubber * Remove references to clean arg from cache-manage * Deleting image that is uploading leaves data * Adding a policy layer for locations APIs * Add/remove/replace locations from an image * Adding multiple locations support to image downloading * Make db properties functions consistent with the DB API * Adds missing error msg for HTTPNotFound exception * Allow storage drivers to add metadata to locations * Fixes image-download error of v2 * On deleting an image, its image_tags are not deleted * Sync gettextutils from oslo * Adding store location proxy to domain * Notify does not occur on all image upload fails * Add location specific information to image locations db * Add custom RPC(Des|S)erializer to common/rpc.py * use tenant:* as swift r/w acl * Add image id to the logging message for upload * Fix cache delete-all-queued-images for xattr * Fix stale process after unit tests complete * Sync install_venv_common from oslo * Fix list formatting in docs * Fix doc formatting issue * Ignore files created by Sphinx build * Use oslo.sphinx and remove local copy of doc theme * Refactor unsupported default store testing * Add Sheepdog store * Fix 'glance-cache-manage -h' default interpolation * Fix 'glance-cache-manage list-cached' for xattr * Dont raise NotFound in simple db image_tag_get_all * Use python module loading to run glance-manage * Removed unusued variables to clean the code * Fixes exposing trace during calling image create API * Pin kombu and anyjson versions * Do not raise NEW exceptions * Port slow, overly assertive v1 functional tests to integration tests * Add a bit of description * Updated documentation to include notifications introduced in Grizzly * Make eventlet hub choice configurable * Don't run store tests without a store! * Import sql_connection option before using it * Fix for unencrypted uris in scrubber queue files * Fix incorrect assertion in test_create_pool * Do not send traceback to clients by default * Use Python 3.x compatible octal literals * Remove explicit distribute depend * Add missing Keystone settings to scrubber conf * Sql query optimization for image detail * Prevent '500' error when admin uses private marker * Replace openstack-common with oslo in HACKING.rst * Patch changes Fedora 16 to 18 on install page * Pass configure_via_auth down to auth plugin * Move sql_connection option into sqlalchemy package * Remove unused dictionary from test_registry_api.py * Remove routes collection mappings * updated content_type in the exception where it is missing * python3: Introduce py33 to tox.ini * Don't make functional tests inherit from IsolatedUnitTest * Add a policy layer for membership APIs * Prevent E500 when listing with null values * Encode headers and params * Fix pydevd module import error * Add documentation on reserving a Glance image * Import strutils from oslo, and convert to it * Sync oslo imports to the latest version 2013.2.b1 --------- * Fix undefined variable in cache * Make passing user token to registry configurable * Respond with 412 after upload if image was deleted * Add unittests for image upload functionality in v1 * Remove glance-control from the test suite * Prevent '500' error when using forbidden marker * Improve unit tests for glance.common package * Improve unit tests for glance.api.v1 module * rbd: remove extra str() conversions and test with unicode * rbd: return image size when asked * Add qpid-python to test-requires * tests: remove unused methods from test_s3 and test_swift * Implement Registry's Client V2 * RBD store uses common utils for reading file chunks * Redirects requests from /v# to /v#/ with correct Location header * Add documentation for query parameters * Small change to 'is_public' documentation * Fix test_mismatched_X test data deletion check * Add GLANCE_LOCALEDIR env variable * Remove gettext.install() from glance/__init__.py * Implement registry API v2 * Add RBD support with the location option * Use flake8/hacking instead of pep8 * Use RBAC policy to determine if context is admin * Create package for registry's client * Compress response's content according to client's accepted encoding * Call os.kill for each child instead of the process group * Improve unit tests for glance.common.auth module * Convert scripts to entry points * Fix functional test 'test_copy_from_swift' * Remove unused configure_db function * Don't raise HTTPForbidden on a multitenant environment * Expand HACKING with commit message guidelines * Redirects requests from /v# to /v#/ * Functional tests use a clean cached db that is only created once * Fixes for mis-use of various exceptions * scrubber: dont print URI of image to be deleted * Eliminate the race when selecting a port for tests * Raise 404 while deleting a deleted image * Fix test redifinitions * Sync with oslo-incubator copy of setup.py and version.py * Gracefully handle qpid errors * Fix Qpid test cases * Imported Translations from Transifex * Fix the deletion of a pending_delete image * Imported Translations from Transifex * Imported Translations from Transifex * Fix functional test 'test_scrubber_with_metadata_enc' * Make "private" functions that shouldn't be exported * Call monkey_patch before other modules are loaded * Adding help text to the options that did not have it * Improve unit tests for glance.api.middleware.cache module * Add placeholder migrations to allow backports * Add GridFS store * glance-manage should not require glance-registry.conf * Verify SSL certificates at boot time * Invalid reference to self in functional test test_scrubber.py * Make is_public an argument rather than a filter * remove deprecated assert_unicode sqlalchemy attribute * Functional tests display the logs of the services they started * Add 'set_image_location' policy option * Add a policy handler to control copy-from functionality * Fallback to inferring image_members unique constraint name * Standardize on newer except syntax * Directly verifying that time and socket are monkey patched * Reformat openstack-common.conf * Fix domain database initialization * Add tests for image visibility filter in db * Add image_size_cap documentation * Return 413 when image_size_cap exceeded * Small change to exception handling in swift store * Remove internal store references from migration 017 * Check if creds are present and not None 2013.1.rc1 ---------- * Delete swift segments when image_size_cap exceeded * bump version to 2013.2 * Don't print sql password in debug messages * fixes use the fact that empty sequences are false * Handle Swift 404 in scrubber * Remove internal store references from migration 015 * Pin SQLAlchemy to 0.7.x * Add unit tests for glance.api.cached_images module * Document the os options config for swift store * Segmented images not deleted cleanly from swift * Do not return location in headers * Fix uniqueness constraint on image_members table * Declare index on ImageMember model * Log when image_size_cap has been exceeded * Publish API version 2.1 * Fix scrubber and other utils to use log.setup() * Switch to final 1.1.0 oslo.config release * Mark password options secret * Fix circular import in glance/db/sqlalchemy * Fix up publicize_image unit test * Fix rabbit_max_retry * Fix visibility on db image_member_find * Fix calls to image_member_find in tests * Characterize image_member_find * Retain migration 12 indexes for table image_properties with sqlite * Insure that migration 6 retains deleted image property index * Fix check_003 method * Ensure disk_ and container_format during upload * Honor metadata_encryption_key in glance domain * Fix v2 data upload to swift * Switch to oslo.config * Update acls in the domain model * Refactor leaky abstractions * Remove unused variable 'image_member_factory' * Generate notification for cached v2 download * A test for concurrency when glance uses sleep * Update documentation to reflect API v2 image sharing * v1 api image-list does not return shared images * Cannot change locations on immutable images * Update db layer to expose multiple image locations * Test date with UTC instead of local timezone * Added better schemas for image members, revised tests * Add pre and check phases to test migration 006 * Fix response code for successful image upload * Remove unused imports * Add pre and check phases to test migration 005 * Add pre and check phases to test migration 004 * Add PostgreSQL support to test migrations * Enable support for MySQL with test migrations * Set status to 'active' after image is uploaded * Removed controversial common image property 'os_libosinfo_shortid' * Parse JSON Schema Draft 10 in v2 Image update * Redact location from notifications * Fix broken JSON schemas in v2 tests * Add migration 021 set_engine_mysql_innodb * Refactor data migration tests * Fix migration 016 for sqlite * Pin jsonschema version below 1.0.0 * Add check for image_locations table * Avoid using logging in signal handlers * monkey_patch the time module for eventlet * Remove compat cfg wrapper * Remove unnecessary logging from migration 019 * Fix migration 015 downgrade with sqlite * Document db_auto_create in default config files * Update openstack.common * Extend the domain model to v2 image data 2013.1.g3 --------- * Add migration 20 - drop images.location * Add migration 19 - move image location data * Filter images by status and add visibility shared * Update oslo-config version * Sync latest install_venv_common.py * Adding new common image properties * Use oslo-config-2013.1b3 * Add migration 18 - create the image_locations table * Create connection for each qpid notification * Add migration to quote encrypted image location urls * Updates OpenStack LLC with OpenStack Foundation * Allowing member to set status of image membership * Add an update option to run_tests.sh * Use install_venv_common.py from oslo * Add status column to image_members * Adding image members in glance v2 api * Fix issues with migration 012 * Add migration.py based on the one in nova * Updated_at not being passed to db in image create * Fix moker typo in test_notifier * Clean dangling image fragments in filesystem store * Sample config and doc for the show_image_direct_url option * Avoid dangling partial image on size/checksum mismatch * Fix version issue during nosetests run * Adding database layer for image members domain model * Image Member Domain Model * Additional image member information * Adding finer notifications * Add LazyPluggable utility from nova * Update .coveragerc * Removed unnecessary code * Use more-specific value for X-Object-Manifest header * Allow description fields to be translated in schema * Mark password config options with secret * Update HACKING.rst per recent changes * Encrypt scrubber marker files * Quote action strings before passing to registry * Fixes 'not in' operator usage * Add to multi-tenant swift store documentation * Replace nose plugin with testtools details * Convert some prints to addDetails calls * Rearrange db tests in prep for testr * Stop using detailed-errors plugin for nose * Add _FATAL_EXCEPTION_FORMAT_ERRORS global * Fix kwargs in xattr BadDriverConfiguration exc * Prints list-cached dates in isoformat * Fail sensibly if swiftclient absent in test * Initialize CONF properly in store func tests * Ensure swift_store_admin_tenants ACLs are set * Remove Swift location/password from messages * Removed unnecessary code * Removed unncessary code * Pull in tarball version fix from oslo * Updated image loop to not use an enumerator * Log exception details * Update version code from oslo * Revert "Avoid testtools 0.9.25" * Avoid testtools 0.9.25 * Update glance config files with log defaults * Sync latest cfg and log from oslo-incubator * Make v2 image tags test not load system policy * Replace custom tearDown with fixtures and cleanup * Update version code from oslo * Use testtools for unittest base class * Stub out find_file... fix policy.json test issue * Remove unused declaration in images.py * Add import for filesystem_store_datadir config * Update v1/images DELETE so it returns empty body * Relax version constraint on Webob-1.0.8 * Set content-length despite webob * Update common openstack code from oslo-incubator * Modify the v2 image tags to use domain model grizzly-2 --------- * Fix broken link in docs to controllingservers * Adding a means for a glance worker to connect back to a pydevd debugger * Use imported exception for update_store_acls * Fix import order nits * Verify size in addition to checksum of uploaded image * Use one wsgi app, one dbengine worker * Set Content-MD5 after calling webob.Response._app_iter__set * Modify the v2 image controller to use domain model * Log error on failure to load paste deploy app * Configure endpoint_type and service_type for swift * Refactor multi-tenant swift store * Add registry_client_timeout parameter * Use io.BufferedIOBase.read() instead of io.BytesIO.getvalue() * Port to argparse based cfg * wsgi.Middleware forward-compatibility with webob 1.2b1 or later * Allow running testsuite as root user * Allow newer boto library versions * Fixed image not getting deleted from cache * Updates keystone middleware classname in docs * v2 API image upload set image status to active * Use auth_token middleware from python-keystoneclient * Add domain proxies that stop unauthorized actions * Add domain proxies that do policy.enforce checks * Use 'notifications' as default notification queue name * Unused variables removed * Fixed deleted image being downloadable by admin * Rewrite S3 functional tests * Add store test coverage for the get_size method * Implement get_size filesystem store method * Add an image repo proxy that handles notifications * Fixed Typo * Return size as int from store get call * Wrap log messages with _() * Add pep8 ignore options to run_tests.sh * Fix typo uudiutils -> uuidutils * Make cooperative reader always support read() * Add an image proxy to handle stored image data grizzly-1 --------- * Allow for not running pep8 * Refactor where store drivers are initialized * Audit error logging * Stop logging all registry client exceptions * Remove unused imports * Add note about urlencoding the sql_connection config opt * Add an image repo to encapsulate db api access * Add an image domain model and related helpers * Fix simple db image_get to look like sqlalchemy * Return 403 on images you can see but can't modify * Fixes is_image_visible to not use deleted key * Ensure strings passed to librbd are not unicode * Use generate_uuid from openstack common * Update uuidutils from openstack common * Code cleanup: remove ImageAddResult class * Lowering certain log lines from error to info * Prevent infinite respawn of child processes * Make run_tests.sh run pep8 checks on bin * Make tox.ini run pep8 checks on bin * Pep8 fixes to bin/glance* scripts * Ensure authorization before deleting from store * Port uuidutils to Glance * Delete from store after registry delete * Unit test remaining glance-replicator methods * Use openstack common timeutils in simple db api * Unit test replication_dump * pin sqlalchemy to the 0.7 series * DRY up image fetch code in v2 API * Return 403 when admin deletes a deleted image * Pull in a versioning fix from openstack-common * Fixes deletion of invalid image member * Return HTTP 404 for deleted images in v2 * Update common to 18 October 2012 * implements selecting version in db sync * add command "status" to "glance-control" * Disallow admin updating deleted images in v2 api * Clean up is_public filtering in image_get_all * SSL functional tests always omitted * Fix scrubber not scrubbing with swift backend * Add OpenStack trove classifier for PyPI * Disallow updating deleted images * Unit test replication_size * Add noseopts and replace noseargs where needed to run_test.sh * Setup the pep8 config to check bin/glance-control * Change useexisting to extend_existing to fix deprecation warnings * Fix fragile respawn storm test * Fix glance filesystem store race condition * Add support for multiple db test classes * Don't parse commandline in filesystem tests * Improve test coverage for replicator's REST client * Correct conversion of properties in headers * Add test for v2 image visibility * change the default sql connection timeout to 60s * Add test for v1 image visibility * FakeAuth not always admin * Add GLANCE_TEST_TMP_DIR environment var for tests * Call setup_s3 before checking for disabled state * Add insecure option to registry https client * Clean up pep8 E128 violations * Rename non-public method in sqlalchemy db driver * Add image_member_update to simple db api * Multiprocess respawn functional test fix * Remove unnecessary set_acl calls * Clean up pep8 E127 violations * Remove notifications on error * Change type of rabbit_durable_queues to boolean * Pass empty args to test config parser * Document api deployment configuration * Clean up pep8 E125 violations * Clean up pep8 E124 violations * Ensure workers set to 0 for all functional tests * image_member_* db functions return dicts * Alter image_member_[update|delete] to use member id * Add test for db api method image_member_create * Add test for image_tag_set_all * Add rabbit_durable_queues config option * Remove extraneous db method image_property_update * Update docs with modified workers default value * Replace README with links to better docs * Remove unused animation module * Drop Glance Client * Enable multi-processing by default * Ensure glance-api application is "greened" * Clean up pep8 E122, E123 violations * Clean up pep8 E121 violations * Fix scrubber start & not scrubbing when not daemon * Clean up pep8 E502, E711 violations * Expand cache middleware unit tests * Change qpid_heartbeat default * Don't WARN if trying to add a scheme which exists * Add unit tests for size_checked_iter * Add functional tests for the HTTP store * Generalize remote image functional test * Add filesystem store driver to new func testing * Add region configuration for swift * Update openstack-common log and setup code * Update v2.0 API version to CURRENT * Set new version to open Grizzly development * Add s3_store_bucket_url_format config option * Ensure status of 'queued' image updated on delete * Fallback to a temp pid file in glance-control * Separate glance cache client from main client * Rewrite Swift store functional tests * Raise bad request early if image metadata is invalid * Return actual unicode instead of escape sequences in v2 * Handle multi-process SIGHUP correctly * Remove extraneous whitespace in config files * Remove db auto-creation magic from glance-manage * Makes deployed APIs configurable * Asynchronously copy from external image source * Sort UUID lists in test_image_get_all_owned * Call do_start correctly in glance-control reload * Sync some misc changes from openstack-common * Sync latest cfg changes from openstack-common * Exception Handling for image upload in v2 * Fix cache not handling backend failures * Instantiate wsgi app for each worker * Require 'status' in simple db image_create * Drop glance client + keystone config docs * Use PATCH instead of PUT for v2 image modification * Delete image from backend store on delete * Document how to deploy cachemanage middleware * Clean up comments in paste files * WARN and use defaults when no policy file is found * Encode headers in v1 API to utf-8 * Fix LP bug #1044462 cfg items need secret=True * Always call stop_servers() after having started them in tests * Adds registry logging * Filter out deleted image properties in v2 api * Limit simple db image_create to known image attrs * Raise Duplicate on image_create with duplicate id * Expand image_create db test * Add test for nonexistent image in db layer * Catch pruner exception when no images are cached * Remove bad error message in glance-cache-manage * Add missing columns to migration 14 * Adds notifications for images v2 * Move authtoken config out of paste * Add kernel/ramdisk_id, instance_uuid to v2 schema * Tweak doc page titles * Drop architecture doc page * Add link to notifications docs on index * Remove repeated image-sharing docs * Tidy up API docs * Log level for BaseContextMiddleware should be warn * Raise Forbidden exception in image_get * Activation notification for glance v1 api * Add glance/versioninfo to MANIFEST.in * HTTPBadRequest in v2 on malformed JSON request body * PEP8 fix in conf.py * Typo fix in glance: existant => existent * Rename glance api docs to something more concise * Drop deprecated client docs * Clean up policies docs page * Remove autodoc and useless index docs * Add nosehtmloutput as a test dependency * Remove partial image data when filesystem is full * Add 'bytes' to image size rejection message * Add policy check for downloading image * Convert limiting_iter to LimitingReader * Add back necessary import * Adds glance registry req id to glance api logging * Make max image size upload configurable * Correctly re-raise exception on bad v1 checksum * Return httplib.HTTPResponse from fake reg conn * Add DB Management docs * Fix auth cred opts for glance-cache-manage * Remove unused imports * Set proper auth middleware option for anon. access * multi_tenant: Fix 'context' is not defined error * Validate uuid-ness in v2 image entity * v2 Images API returns 201 on image data upload * Fixes issue with non string header values in glance client * Fix build_sphinx setup.py command * Updates Image attribute updated_at * Add policy enforcment for v2 api * Raise 400 error on POST/PUTs missing request bodies folsom-3 -------- * Mark bin/glance as deprecated * Return 201 on v2 image create * Ignore duplicate tags in v2 API * Expose 'protected' image attribute in v2 API * Move to tag-based versioning * Update restrictions on allowed v2 image properties * Reveal v2 API as v2.0 in versions response * Add min_ram and min_disk to v2 images schema * Filter out None values from v2 API image entity * Refactor v2 images resource unit tests * Use container_format and disk_format as-is in v2 * Make swift_store_admin_tenants a ListOpt * Update rbd store to allow copy-on-write clones * Call stop_servers() in direct_url func tests * Drop unfinshed parts of v2 API * Fix a couple i18n issues in glance/common/auth.py * Sync with latest version of openstack.common.notifier * Sync with latest version of openstack.common.log * Sync with latest version of openstack.common.timeutils * Sync with latest version of openstack.common.importutils * Sync with latest version of openstack.common.cfg * Allows exposing image location based on config * Do not cache images that fail checksum verfication * Omit deleted properties on image-list by property * Allow server-side validation of client ssl certs * Handle images which exist but can't be seen * Adds proper response checking to HTTP Store * Use function registration for policy checks * fix the qpid_heartbeat option so that it's effective * Add links to image access schema * ^c shouldn't leave incomplete images in cache * uuid is a silly name for a var * Support master and slave having different tokens * Add a missing header strip opportunity * URLs to glance need to be absolute * Use with for file IO * Add swift_store_admin_tenants option * Update v1/v2 images APIs to set store ACLs * Use event.listen() instead of deprecated listeners kwarg * Store context in local thread store for logging * Process umask shouldn't allow world-readable files * Make TCP_KEEPIDLE configurable * Reject rather than ignore forbidden updates * Raise HTTPBadRequest when schema validation fails * Expose 'status' on v2 image entities * Simplify image and access_record responses * Move optional dependencies from pip-requires to test-requires * Fix dead link to image access collection schema * Add in missing image collection schema link * Drop static API v2 responses * Include dates in detailed image output * Update image caching middleware for v2 URIs * Ensure Content-Type is JSON-like where necessary * Have non-empty image properties in image.delete payload * Add Content-MD5 header to V2 API image download * Adds set_acls function for swift store * Store swift images in separate containers * Include chunk_name in swift debug message * Set deleted_at field when image members and properties are deleted * Use size_checked_iter in v2 API * Honor '--insecure' commandline flag also for keystone authentication * Make functional tests listen on 127.0.0.1 * Adds multi tenant support for swift backend * Provide stores access to the request context * Increase wait time for test_unsupported_default_store * Match path_info in image cache middleware * Dont show stack trace on command line for service error * Replace example.com with localhost for some tests * Fix registry error message and exception contents * Move checked_iter from v1 API glance.api.common * Support zero-size image creation via the v1 API * Prevent client from overriding important headers * Updates run_tests.sh to exclude openstack-common * Use openstack.common.log to log request id * Update 'logging' imports to openstack-common * Make get_endpoint a generic reusable function * Adds service_catalog to the context * Add openstack-common's local and notifier modules * Making docs pretty! * Removing 'Indices and tables' heading from docs * Remove microseconds before time format conversion * Add bin/glance-replicator to scripts in setup.py * Initial implementation of glance replication * Generate request id and return in header to client * Reorganize context module * Add openstack.common.log * Ignore openstack-common in pep8 check * Keystone dep is not actually needed * Report size of image file in v2 API * Expose owner on v2 image entities * Add function tests for image members * Allow admin's to modify image members * Allow admins to share images regardless of owner * Improve eventlet concurrency when uploading/downloading * Simplify v2 API functional tests folsom-2 -------- * Fix IndexError when adding/updating image members * Report image checksum in v2 API * Store properties dict as list in simple db driver * Use PyPI for swiftclient * Refactor pagination db functional tests * Combine same-time tests with main db test case * Add retry to server launch in respawn test * Reorder imports by full import path * Adds /v2/schemas/images * Implement image filtering in v2 * Include all tests in generated tarballs * Allow CONF.notifier_strategy to be a full path * Add image access records schema for image resources * Remove image members joinedload * Clean up image member db api methods * Retry test server launch on failure to listen * Make image.upload notification send up2date metadata * Added schema links logic to image resources * Simplify sqlalchemy imports in driver * Reduce 'global' usage in sqlalchemy db driver * Standardize logger instantiation * Add link descriptor objects to schemas * Fix exception if glance fails to load schema * Move the particulars of v2 schemas under v2 * Remove listing of image tags * Set up Simple DB driver tests * Trace glance service on launch failure * Revert "Funnel debug logging through nose properly." * Capture logs of failing services in assertion msg * Remove some more glance-cache PasteDeploy remnants * Fix typo of conf variable in config.py * Remove unused imports in db migrations * Increase timeout to avoid spurious test failures * adds missing import and removes empty docstring * Convert db testing to use inheritance * Clean up .pyc files before running tests * make roles case-insensitive * Funnel debug logging through nose properly * Fix typo of swift_client/swiftclient in store_utils * Stop revealing sensitive store info * Avoid thread creation prior to service launch * Don't use PasteDeploy for scrubber and cache daemons * Remove some unused glance-cache-queue-image code * Implement pagination and sorting in v2 * Turn off SQL query logging at log level INFO * Default db_auto_create to False * Use zipballs instead of git urls * Add metadata_encryption_key to glance-cache.conf * Fix help messages for --debug * Use python-swiftclient for swift store * Fix to not use deprecated response.environ any more * Import db driver through configuration * Move RequestContext.is_image_* methods to db layer * Begin replacement of sqlalchemy driver imports * webob exception incorrectly used in v1 images.py * Add tests and simplify GlanceExceptions * Update default values for known_stores config * Remove the conf passing PasteDeploy factories * Port remaining code to global conf object * Made changes to adhere to HACKING.rst specifications * Use openstack-common's policy module * Re-add migrate.cfg to tarball * Implements cleaner fake_request * Create 'simple' db driver * Glance should use openstack.common.timeutils * Clean up a few ugly bits from the testing patch * Fix typo in doc * Add cfg's new global CONF object * fix side effects from seekability test on input file * Just use pure nosetests * Fix coverage jobs. Also, clean up the tox.ini * Move glance.registry.db to glance.db * Glance should use openstack.common.importutils * Add read-only enforcement to v2 API * Add a base class for tests * Expose tags on image entities in v2 API * Add additional info. to image.delete notification * Expose timestamps on image entities in v2 API * Sync with latest version of openstack.common.cfg * Enable anonymous access through context middleware * Add allow_additional_image_properties * Fix integration of image properties in v2 API * Lock pep8 at v1.1 * Lock pep8 to version 0.6.1 in tox.ini * Fail gracefully if paste config file is missing * Add missing files to tarball * Remove unused imports in setup.py * Adds sql_ config settings to glance-api.conf * Correct format of schema-image.json * Fix paste to correctly deploy v2 API * Add connection timeout to glance client * Leave behind sqlite DB for red functional tests * Support DB auto-create suppression * Fix glance-api process leak in respawn storm test * Stubout httplib to avoid actual http calls * Backslash continuation removal (Glance folsom-1) * Implement image visibility in v2 API * Add min_ram and min_disk to bin/glance help * Implements blueprint import-dynamic-stores * Add credential quoting to Swift's StoreLocation * Combine v2 functional image tests * Simplify JSON Schema validation in v2 API * Expose deployer-specific properties in v2 API * Test that v2 deserializers use custom schemas * Load schema properties when v2 API starts * Support custom properties in schemas for v2 API * Fix tiny format string nit in log message * Fixes bug 997565 * Allow chunked image upload in v2 API * wsgi: do not respawn on missing eventlet hub * Implement v2 API access resource * Disallow image uploads in v2 API when data exists * Implement v2 API image tags * Use ConfigOpts.find_file() for policy and paste * Implement image data upload/download for v2 API * Use sdist cmdclass from openstack-common * glance-api: separate exit status from message * Update noauth caching pipeline to use unauth-ctx * Return 204 from DELETE /v2/images/ * Add localization catalog and initial po files to Glance. Fix bug 706449 * Add /v2 to sample glance-api-paste.ini * Basic functionality of v2 /images resource * Split noauth context middleware into new class * Add -c|--coverage option to run_tests.sh * Convert glance to glance/openstack/common/setup.py * Update glance to pass properly tenant_name * Cleanup authtoken examples * Support for directory source of config files * Support conf from URL's with versions * Auto generate AUTHORS file for glance * Integrate openstack-common using update.py * Fixes LP #992096 - Ensure version in URL * Begin functional testing of v2 API * Fixes LP #978119 - cachemanagement w/o keystone * Omit Content-Length on chunked transfer * Fix content type for qpid notifier * Remove __init__.py from locale dir * Fix i18n in glance.notifier.notify_kombu * Override OS_AUTH_URL when running functional tests * remove superfluous 'pass' * fix bug lp:980892,update glance doc * Add a space to fix minor typo in glance help * Suppress pagination on non-tty glance index * Kill glance-api child workers on SIGINT * Ensure swift auth URL includes trailing slash * add postgresql support to test_migrations * 012_id_to_uuid: Also convert ramdisk + kernel ids * API v2 controller/serialization separation * search for logger in PATH * Set install_requires in setup.py * Minor grammar corrections * Bootstrapping v2 Image API implementation * Fix db migration 12 * Remove unused imports * Reorganize pipelines for multiple api versions * Skip test depending on sqlite3 if unavailable * Defaulted amazon disk & container formats * Compile BigInteger to INTEGER for sqlite * Updated RST docs on containers, fewer references to OVF format * rename the right index * Reject excessively long image names * Test coverage for update of image ownership * Add MySQLPingListener() back * Add support for auth version 2 * Run version_control after auto-creating the DB * Allow specifying the current version in 'glance-manage version_control' * Publish v2 in versions responses * Allow yes-like values to be interpreted as bool * Support owner paramater to glance add * Adding versioned namespaces in test dir * Typo * Ensure functional db connection in configure_db() * Set content_type for messages in Qpid notifier * Avoid leaking secrets into config logging * Fixes lp959670 * Send output of stty test cmd to stderr * Use unique per-test S3 bucket name * Specify location when creating s3 bucket * Open Folsom * Update 'bin/glance add' docstring *_format options * Ensure all unauthorized reponses return 403 * Avoid leaking s3 credentials into logs * Avoid glance-logcapture displaying empty logs * Add 'publicize_image' policy * Fixed db conn recovery issue. Fixes bug 954971 * tox tests with run_tests.sh instead of nosetests * Don't use auth url to determine service protocol * Use tenant/user ids rather than names * Update context middleware with supported headers * Fixes LP #957401 - Remove stray output on stderr * check connection in Listener. refer to Bug #943031 * Avoid tests leaking empty tmp dirs * Remove keystone.middleware.glance_auth_token * Updating version of Keystone * Add policy checks for cache manage middleware * nose plugin to capture glance service logs * Add new UnexpectedStatus exception * Do not error when service does not have 'type' * Disambiguates HTTP 401 and HTTP 403 in Glance. Fixes bug 956513 * Add admin_role option * Remove references to admin_token * Remove glance-cache-queue-image * Remove dependency on apiv1app from cachemanage * Return 403 when policy engine denies action * Add error checking to get_terminal_size * Well-formed exception types for 413 & 503 * Ensure copy and original image IDs differ * Include babel.cfg and glance.pot in tarballs * Updating authentication docs * General cleanup * General docs cleanup * Remove todolist from docs * Add note about cache config options * Change CLIAuth arg names * Retry sendfile on EAGAIN or EBUSY * Add module name to ClientException * Update cli docs * Remove 'community' doc page * Removing registry spec from docs * Fixes LP#934492 - Allow Null Name * Refresh SSL cfg after parsing service catalog entry * Fix typo in tox.ini * Glance cache updates to support Keystone Essex * updates man page for glance-scrubber. this time with extra pep8 scrubbing powers. Fixes bug 908803 * Update tox.ini for jenkins * Replaced use of webob.Request.str_param * Update paste file to use service tenant * Update bin/glance to allow for specifying image id * Fix deprecated warnings * Remove trailing whitespaces in regular file * add git commit date / sha1 to sphinx html docs * Glance skip prompting if stdin isn't a tty * Allow region selection when using V2 keystone * Disallow file:// sources on location or copy-from * Progress bar causes intermittent test failures * Added first step of babel-based translations * Complete fix for modification of unowned image * Fix update of queued image with location set * Support copy-from for queued images * Add checksum to an external image during add * Align to jenkins tox patterns * Fix MANIFEST.in to include missing files * Fix exception name * Correct kernel/ramdisk example in docs * Create sorting/pagination helper function * Support new image copied from external storage * blueprint progressbar-upload-image * Avoid TestClient error on missing '__mro__' attr * disk/container_format required on image activate * Require container & disk formats on image create * Support non-UTC timestamps in changes-since filter * Return 503 if insufficient permission on filestore * Adds README.rst to the tarball * Ensure StorageFull only raised on space starvation * Require auth URL if keystone strategy is enabled * 003_add_disk_format.py: Avoid deadlock in upgrade * Function uses 'msg' not 'message' * Fix paging ties * Ensure sane chunk size when pysendfile unavailable * New -k/--insecure command line option * Add a generic tox build environment * Fix pep8 error * Update Authors file * Implement blueprint add-qpid-support * Include glance/tests/etc * Don't fail response if caching failed * Force auth_strategy=keystone if --auth_url or OS_AUTH_URL is set * Make Glance work with SQLAlchemy 0.7 * Use sendfile() for zero-copy of uploaded images * Respawn glance services on unexpected death * Blueprint cli-auth: common cli args * Prep tox config for jenkins builds * Get rid of DeprecationWarning during db migration * Add --capture-output option to glance-control * Add filter validation to glance API * Fixes LP 922723 * Typofix is_publi -> is_public * Add --await-child option to glance-control * Fix Bug #919255 * Cap boto version at 2.1.1 * Simplify pep8 output to one line per violation * Handle access restriction to public unowned image * Check service catalogue type rather than name * Restore inadvertantly dropped lines * Include the LICENSE file in the tarball * Change xattr usage to be more broadly compatible * Fix mixed usage of 's' and 'self' * Don't force client to supply SSL cert/key * Few small cleanups to align with Nova essex-3 ------- * Adds documentation for policy files * Client.add_image() accepts image data as iterable * More flexible specification of auth credentials * glance-api fails fast if default store unsupported * Bug #909574: Glance does not sanity-check given image size on upload * glance-control need not locate a server's config file (lp#919520) * Bug#911599 - Location field wiped on update * Return 400 if registry returns 400 * Set url's on AuthBadRequest exceptions * Add policy checking for basic image operations * Swallow exception on unsupported image deletion * Ensure we only send a single content-type header * Multi-process Glance API server support * Set size metadata correctly for remote images * Make paste.ini file location configurable * Avoid the need for users to manually edit PasteDeploy config in order to switch pipelines * Split out paste deployment config from the core glance *.conf files into corresponding *-paste.ini files * Fixes LP Bug#913608 - tests should be isolated * Set correct Content-Length on cached remote images * Implement retries in notify_kombu * Return correct href if bind_host is 0.0.0.0 * Remove assertDictEqual for python 2.6 compatibility * Add optional revision field to version number * LP Bug#912800 - Delete image remain in cache * Add notifications for sending an image * Bug #909533: Swift uploads through Glance using ridiculously small chunks * Add Fedora clauses to the installing document * Remove doc/Makefile * Fixes incorrect URI scheme for s3 backend * Add comments for swift options in glance-api.conf * Split notification strategies out into modules * fix bug 911681 * Fix help output for inverse of BoolOpt * PEP8 glance cleanup * Add more man pages * Set execute permissions on glance-cache-queue-image * Add a LICENSE file * Add ability to specify syslog facility * Install an actual good version of pip * Bug #909538: Swift upload via Glance logs the password it's using * Add tox.ini file * Synchronize notification queue setup between nova and glance * Fixes keystone auth test failures in python 2.6 * Removed bin/glance's TTY detection * Fixes request with a deleted image as marker * Adds support for protecting images from accidental deletion * Fix for bug 901609, when using v2 auth should use /v2.0/tokens path * Updated glance.registry.db for bug 904863 * Removing caching cruft from bin/glance * Fixes LP Bug#901534 - Lost properties in upload * Update glance caching middleware so doesn't try to process calls to subresources. Fixes LP bug #889209 * Ensure functional tests clean up their images * Remove extra swift delete_object call * Add missing files to tarball * Allow glance keystone unit tests to run with essex keystone * Convert glance to use the new cfg module * Add new cfg module * Lock keystone to specific commit in pip-requires * Add the missing column header to list-cached * Rename 'options' variables to 'conf' * Add generic PasteDeploy app and filter factories * Secondary iteration of fix for bug 891738 * Rename .glance-venv to .venv * Fix for bug 900258 -- add documentation for '--url' glance cli option * Add --url option to glance cli * Fixes LP Bug#850377 * Fixes LP Bug#861650 - Glance client deps * Added some examples for "glance add" * Bug#894027: use correct module when building docs * Adds option to set custom data buffer dir * Fix bug 891738 * Added missing depend on nosexcover * Removed some cruft * Fixes LP Bug#837817 - bin/glance cache disabled * Separating add vs general store configuration * Fixes LP Bug#885341 - Test failure in TestImageCacheManageXattr * Making prefetcher call create_stores * Fix handle get_from_backend returning a tuple * Casting foreign_keys to a list in order to index into it * Using Keystone's new port number 35357 * Adding admin_token to image-cache config * Removing assertGreaterEqual * Correcting image cleanup in cache drivers * Adding tests to check 'glance show ' format * Update 'glance show' to print a valid URI. Fixes bug #888370 * Gracefully handle image_cache_dir being undefined * Remove unused versions pipeline from PasteDeploy config * Allow glance-cache-* find their config files * Add some test cases for glance.common.config * Fix name error in cache middleware * Check to make sure the incomplete file exists before moving it during rollback. Fixes bug #888241 * Fix global name 'sleep' is not defined in wsgi.py. Fixes bug #888215 * Fixes LP Bug#878411 - No docs for image cache * Fix typo in the cached images controller essex-1 ------- * load gettext in __init__ to fix '_ is not defined' * Adds option to encrypt 'location' metadata * Fix LP Bug#885696 two issues with checked_iter * Fix Keystone API skew issue with Glance client * Fixed test failure in Python 2.6 * Glance redirect support for clients * Fixes LP Bug#882185 - Document Swift HTTPS default * Fixes LP Bug#884297 - Install docs should have git * Add "import errno" to a couple of files * Consolidate glance.utils into glance.common.utils * Correcting exception handling in glance-manage * More cache refactoring - Management Middleware * Fixes LP Bug#882585 - Backend storage disconnect * Convert image id value to a uuid * Remove 'location' from POST/PUT image responses * Removing glance-upload * Adds Driver Layer to Image Cache * Removed 'mox==0.5.0' and replaced with just 'mox' in tools/pip-requires * Removing duplicate mox install in pip-requires * Add .gitreview config file for gerrit * Making TCP_KEEPIDLE socket option optional * Overhauls the image cache to be truly optional * Fixing functional tests that require keystone * Fixes LP Bug#844618 - SQLAlchemy errors not logged * Additions to .gitignore * Better document using Glance with Keystone * Fixes LP Bug#872276 - small typo in error message * Adds SSL configuration params to the client * Increases test coverage for the common utils * Refactoring/cleanup around our exception handling * Port Authors test to git * Add RBD store backend * Fixes LP Bug#860862 - Security creds still shown * Extract image members into new Glance API controller * Refactoring registry api controllers * Returning functionality of s3 backend to stream remote images * Make remote swift image streaming functional * Improving swfit store uri construction * Fixes LP Bug #850685 * Do not allow min_ram or min_disk properties to be NULL and if they are None, make sure to default to 0. Fixes bug 857711 * Implementing changes-since param in api & registry * Documenting nova_to_os_env.sh tool * Added min_disk and min_ram properties to images Fixes LP Bug#849368 * Fixing bug 794582 - Now able to stream http(s) images * Fixes LP Bug#755916 - Location field shows creds * Fixes LP Bug #804429 * Fixes Bug #851216 * Fixes LP Bug #833285 * Fixes bug 851016 * Fix keystone paste config for functional tests * Updating image status docs * * Scrubber now uses registry client to communicate with registry * glance-api writes out to a scrubber "queue" dir on delete * Scrubber determines images to deleted from "queue" dir not db * Fixes LP Bug#845788 * Open Essex * Remove PWD from possible config_file_dirs * Update paste config files with keystone examples. see ticket: lp839559 * Adding Keystone support for Glance client * Fix cached-images API endpoint * Bug fix lp:726864 * Fixes Bug: lp825024 * Add functional tests * Switch file based logging to WatchedFileHandler for logrotate * Fixes LP Bug #827660 - Swift driver fail 5G upload * Bug lp:829064 * Bug lp:829654 * Update rfc.sh to use 'true' * Addresses glance/+spec/i18n * Addresses glance/+spec/i18n * Add rfc.sh for git review * Add support for shared images * Add notifications for uploads, updates and deletes * Bug Fix lp:825493 * Bug fix lp:824706 * Adds syslog support * Fixes image cache enabled config * Improves logging by including traceback * Addresses glance/+spec/i18n * casting image_id to int in db api to prevent false matching in database lookups * Addresses Bug lp:781410 * Removes faked out datastore entirely, allowing the DB API to be unit tested * Consolidates the functional API test cases into /glance/tests/functional/test_api.py, adds a new Swift functional test case, verified that it works on Cloud Files with a test account * breaking up MAX_ITEM_LIMIT and making the new values configurable * Add @skip_if_disabled decorator to test.utils and integrate it into the base functional API test case. The S3 functional test case now uses test_api.TestApi as its base class and the setUp() method sets the disabled and disabled_message attributes that the @skip_if_disabled decorator uses * Adds swift_enable_snet config * Fixes bug lp:821296 * Detect python version in install_venv * Implemented @utils.skip_test, @utils.skip_unless and @utils.skip_if functionality in glance/test/utils.py. Added glance/tests/unit/test_skip_examples.py which contains example skip case usages * Changed setup.py to pull version info from git * Removes the call to webob.Request.make_body_seekable() in the general images controller to prevent the image from being copied into memory. In the S3 controller, which needs a seekable file-like object when calling boto.s3.Key.set_contents_from_file(), we work around this by writing chunks of the request body to a tempfile on the API node, then stream this tempfile to S3 * Make sure we're passing the temporary file in a read-mode file descriptor to S3 * Removes the call to webob.Request.make_body_seekable() in the general images controller to prevent the image from being copied into memory. In the S3 controller, which needs a seekable file-like object when calling boto.s3.Key.set_contents_from_file(), we work around this by writing chunks of the request body to a tempfile on the API node, then stream this tempfile to S3 * - removed curl api functional tests - moved httplib2 api functional tests to tests/functional/test_api.py * merging trunk * Make tests a package under glance * removing curl tests and moving httplib2 tests * Move tests under the glance namespace * Add filter support to bin/glance index and details calls * merging trunk * Update registry db api to properly handle pagination through sorted results * Our code doesn't work with python-xattr 0.5.0, and that's the version installed in RH/Centos :( Andrey has updated the RPM config to specify 0.6.0, and this does the same to pip-requires * Replaced occurances of |str(e)| with |"%s" % e| * First round of refactoring on stores * Remove expected_size stuff * Make calling delete on a store that doesn't support it raise an exception, clean up stubout of HTTP store and testing of http store * adding sort_key/sort_dir to details * merging lp:~rackspace-titan/glance/registry-marker-lp819551 * adding sort_key/sort_dir params * adding --fixes * adding complex test cases to recreate bug; updating db api to respect marker * Add configuration check for Filesystem store on configure(), not every call to add() * Refactor S3 store to make configuration one-time at init versus every method call invocation * Refactor Swift store to make configuration one-time at init versus every method call invocation * Forgot to add a new file.. * Refactors stores to be stateful: * Make sure xattr>=0.6.0 in pip-requires * updating documentation * making limit option an integer * updating broken tests * adding limit/marker to bin/glance details call * adding limit/marker params to bin/glance index * merging trunk * Use of "%default" in help string does not work, have to use "%(default)s". Per the 4th example http://docs.python.org/dev/library/argparse.html#prog * Added nose-exclude to pip-requires * Installed nose-exclude, ./run_tests.sh --unittests-only add '--exclude-dir=tests/functional' to NOSEARGS * This one has been bugging me for a while, finally found out how to use the local default variable in the help string * adding --fixes to commit * Replaced occurances of |str(e)| with |"%s" % e| * Completes the S3 storage backend. The original code did not actually fit the API from boto it turned out, and the stubs that were in the unit test were hiding this fact * Fix for boto1.9b issue 540 (http://code.google.com/p/boto/issues/detail?id=540) * Remove unnecessary hashlib entry in pip-requires * Add myself to Authors (again) * hashlib exists all of the way back to python 2.5, there's no need to install an additional copy * Adds image_cache_enabled config needed to enable/disable the image-cache in the glance-api * Add more unit tests for URI parsing and get_backend_class() (which is going away in refactor-stores branch, but oh well..) * Added unit tests for swift_auth_url @property. It was broken. startwith('swift+http') matches swift+https first * Don't tee into the cache if that image is already being written * Re-add else: raise * Final fixes merging Rick's swift_auth_url @property with previous URI parsing fixes that were in the S3 bug branch.. * merge trunk * This updates the pep8 version in pip-requires and updates run_tests.sh to provide a '-p' option that allows for just pep8 to be run * Adding back image_cache_enabled config option for glance-api * Don't tee same image into cache multiple times * Fixes two things: * adding run_tests.sh -p * PEP8 whitespace fix * Swift client library needs scheme * Add tests for bad schemes passed to get_backend_class() * Add tests for bad URI parsing and get_backend_class() * Include missing bin/glance-scrubber in tarball * Include bin/glance-scrubber in tarball binaries * One more auth_tok-related change, to make it easier for nova to use the client without violating any abstraction boundaries * Add fix for Bug #816386. Wait up to 5 min for the image to be deleted, but at least 15 seconds * remove superfluous if statement * Loop up to 5 min checking for when the scrubber deletes * Typo in error condition for create_bucket_on_put, make body seekable in req object, and remove +glance from docs and configs * Add functional test case for checking delete and get of non-existing image * New local filesystem image cache with REST managment API * PEP8 Fixes * Using DELETE instead of POST reap_invalid, reap_stalled * Forgot to put back fix for the get_backend_class problem.. * Adding logging if unable to delete image cache file * Add test case for S3 s3_store_host variations and fixes for URL bug * Ensure image is active before trying to fetch it * Boy, I'm an idiot...put this in the wrong branch directory.. * Handling ZeroDivision Error * Using alternate logging syntax * Missing import of common.config in S3 driver * Tighten up file-mode handling for cache entry * Adding request context handling * Merging trunk * Fixed review stuff from Brian * Allow delaying the actual deletion of an image * have the scrubber init a real context instead of a dict * merge trunk * Adds authentication middleware support in glance (integration to keystone will be performed as a piece of middleware extending this and committed to the keystone repository). Also implements private images. No limited-visibility shared image support is provided yet * Take out extraneous comments; tune up doc string; rename image_visible() to is_image_visible(); log authorization failures * use runs_sql instead of hackery * Updating setup.py per bin/image_cache removal * Removing bin/image_cache directory * Removing cache enabled flag from most confs * Removing imagecache from default WSGI pipeline * Allow plugging in alternate context classes so the owner property and the image_visible() method can be overridden * Make a context property 'owner' that returns the tenant; this makes it possible to change the concept of ownership by using a different context object * Unit tests for the context's image_visible() routine * We don't really need elevate().. * Merging in adding_image_caching * Importing module rather than function * PEP 8 fixes * Adding reap stalled images * Returning number of files deleted by cache-clear * Returning num_reaped from reap_invalid * Moving bin to image_cache/ * Fixing comment * Adding reaper script * Adding percent done to incomplete and invalid image listing * Renaming tmp_path to incomplete_path * Renaming tmp_path to incomplete_path * Renaming purge_all clear, less elegant variation * Refactor to use lookup_command, so command map is used in one place * Refactoring to use same command map between functions * Renaming to cache-prefetching * Renaming to cache-prefetch * Renaming to cache-purge-all * Renaming to cache-purge * Renaming to cache-invalid * Beginning to normalize names * Refactoring out common code * Refactoring prefetch * Refactoring purge * Refactoring purge_all * Refactoring listing of prefetching images * Using querystring params for invalid images * Link incoming context with image owner for authorization decisions * How in the world did I manage to forget this? *sigh* * Make tests work again * merge trunk * pull-up from trunk * This patch: * PEP8 nit * Added fix for Bug #813291: POST to /images setting x-image-meta-id to an already existing image id causes a 500 error * One more try.. * Yet another attempt to fix URIs * Add in security context information * Moving cached image list to middleware * Initial work on moving cached_images to WSGI middleware * API is now returning a 409 error on duplicate POST. I also modified the testcase to expect a 409 response * Add owner to database schema * Fix URI parsing on MacOSX - Python 2.6.1 urlparse bugs * Namespacing xattr keys * PEP8 fixes * Added 3 tests in tests/functional/test_httplib2_api.py to validate is_public filtering works * left in 2 fixes.. removing redundant fix * If meta-data contains an id field, pass it to _image_update() * Adding functional test to show bug #813291 * fixed an inline comment * removed pprint import, and added check for other 3 images to make sure is_public=True * Added 3 tests to validate is_public filtering works * Completed rewrite of tests/functional/test_curl_api.py using httplib2 * Changes the default filtering of images to only show is_public to actually use a default filter instead of hard coding. This allows us to override the default behavior by passing in a new filter * removing pprint import * completed rewrite of test_ordered_images().. this completes rewrite of test_curl_api using httplib2 * test_ordered_images() missing closing self.stop_servers() * finished rewrite of test_filtered_images() * add tests and make None filters work * Change default is_public = True to just set a default filter instead of hard coding so it can be overridden * make the tests work with new trunk * merge trunk * Refactoring PrettyTable so it doesn't print the lines itself * Adding pruner and prefetcher to setup.py * Removing extraneous text * PEP 8 fixes * Adding prefetching list to bin/glance * More cleanups * Adding prefetching of images * Overhaul the way that the store URI works. We can now support specifying the authurls for Swift and S3 with either an http://, an https:// or no prefix at all * Typo fix * Removing test exception * PEP 8 fixes * Adding Error to invalid cache images * Show invalid images from bin/glance * Improving comments * Cleaning up cache write * Moving xattrs out to utils * Clip and justify columns for display * Including last accessed time in cached list * Adding more comments * Adding hit counter * Pruning invalid cache entries after grace period * Clear invalid images when purging all cached images * Rollback by moving images to invalid_path * Improving comments * PEP8 fixes * Adding cached image purge to bin/glance * Adding purge all to bin/glance * Adding catch_error decorator to bin/glance * Adding 'cached' command to bin/glance * Write incomplete files to tmp path * Adding purge_all, skip if set if xattrs arent supported * Adding purge cache API call * Adding API call to query for cache entries * Create bin/glance-pruner * Adding image_caching * rewrote test_traceback_not_consumed(), working on test_filtered_images() * Only changes is reverting the patch that added migration to configure_db() and resets the in-memory SQLite database as the one used in functional testing. Yamahata's commits were unmodified.. * Reverts commit that did db migration during configure_db() and makes functional tests use in-memory database again. The issues we were seeing had to do with the timeout not being long enough when starting servers with disk-based registry databases and migrate taking too long when spinning up the registry server... this was shown in almost random failures of tests saying failure to start servers. Rather than increase the timeout from 3 seconds, I reverted the change that runs migrate on every startup and cut the total test duration down about 15 seconds * merged glance trunk * updated Authors * Resolves bug lp:803260, by adding a check to ensure req.headers['Accept'] exists before it gets assigned to a variable * run_tests.py: make test runner accepts plugins * run_tests.py: make run_tests.py work * Fix the poor error handling uncovered through bug in nova * Added stop_servers() to the end of the test cases * adding testing & error handling for invalid markers * removed pprint import * removed extra space on test_queued_process_flow method definition * removing commented out line * merged in lp:~jshepher/glance/functional_tests_using_httplib2_part2 * applied requested fix in merge-prop * Removing ordering numbers from the test cases, per jay pipes * cleaning up the 'no accept headers' test cases. this should fail until Bug lp:803260 is resolved * Cleaning up docstring spacing * rewrite of test_size_greater_2G_mysql from test_curl_api.py using httplib2. All tests currently pass * completed rewrite of test_003_version_variations. bug lp:803260 filed about step #0, and noted as a comment in code * Fix for bug 803188. This branch also proposed for merging into trunk * miss-numbering of steps * fixing pep8 violation * Added a check to ensure req.headers['Accept'] exists before it gets assigned to a variable. All unit/functional tests pass with this patch * half way done with rewrite of test_003_version_variations.. step #0 causes a 500 error unless we supply an Accept header * Prevent query params from being set to None instead of a dict * removing rogue print * fixing issue where filters are set to None * Backport for bug 803055 * rewrote test_002_queued_process_flow from test_curl_api.py, all 6 steps pass against trunk revno:146 * Backport for bug 803055 * Prevent clients from adding query parameters set to None * ignores None param values passed to do_request * cleaning up docstrings * merging trunk * docstring * Added sort_key and sort_dir query params to apis and clients * fixing one last docstring * docstrings\! * unit/test_config.py: make it independent on sys.argv * run_tests.py: make test runner accepts plugins * reverting one import change; another docstring fix * docstring * Switch image_data to be a file-like object instead of bare string in image creating and updating Without this Glance loads all image into memory, then copies it one time, then writes it to temp file, and only after all this copies image to target repository * Add myself to Authors file * cleaning up None values being passed into images_get_all_public db call * adding base client module * restructuring client code * merging trunk * Explicitly set headers rather than add them * fixing httplib2 functional test that was expecting wrong content-type value * merging trunk * rewrite of test_get_head_simple_post from tests/functional/test_curl_api.py using httplib2 * adding assert to check content_type in GET /images/ test * Explicitly setting Content-Type, Content-Length, ETag, Location headers to prevent duplication * Bug #801703: No logging is configured for unit tests * Bug #801703: No logging is configured for unit tests * Change image_data to body_file instead of body * reset _MAKER every test and make sure to stop the servers * Trunk merge, changed returned content-type header from 'application/octet-stream' to 'text/html; charset=UTF-8, application/octet-stream' * yea python strings * updated main docstring, as it was directly coppied from test_curl_api.py * merged trunk * refactoring for Jay * make image data a constant * Fixes build failures due to webob upgrade. Updated pop-requires as well * upgrading webob and fixing tests * - refactoring wsgi code to divide deserialization, controller, serialization among different objects - Resource object acts as coordinator * updating client docs * fixing bad request error messages * making SUPPORTED_* lists into tuples * slight refactoring * updating docs * adding ordering support to glance api * adding support to registry server and client for sort_key and sort_dir params * re-ordered imports, using alpha-ordering * removing unnecessary unittest import * moved httplib2 tests to their own test case file, and uncommented md5 match * updating docs; adding support for status filter * adding query filters to bin/glance details * adding query filters to bin/glance index * forgot to remove pprint import * adding hashlib as a dependency to pip-requires (not 100% sure it is not part of the base install though) * fixed pep8 violation * rewote the test #7 - #11 for testcase (test_get_head_simple_post) * refactoring for Brian * refactoring from Rick's comments * Added httplib2 dependency to tools/pip-requires * rewriting functional tests to utilize httplib2 instead of curl * make sure it runs as a daemon for the tests * default to no daemon * also allow for daemon in the config file so that we can test it easier * default to non-daemon mode * change order of paramaters and make event optional * initial refactoring from Jay's comments * remove eventlet import and leftover function from previous refactoring * remove file that got resurrected by accident * fixed test case * add functional tests of the scrubber and delayed_delete * start the scrubber in addition to the api and registry * add glance-scrubber to glance-control * call it a Daemon, cuz it is * Update Authors * add the function to the stubs * cleanup * adding tests for wsgi module * removing rogue print * further refactoring * adding refactored wsgi code from nova; moving registry api to new wsgi * delayed scrubbing now works * add the scrubber startup script * remove unnecessary option * add pending_delete to stub api * pep8 fixed * pep8 fixes * pass in the type we want so it gets converted properly * self leaked ;( * only return the results that we need to act on * allow passing of time to get only results earlier than the time' * server and scrubber work * update the docstring to reflect current * pass in a wakeup_time for the default time between database hits * start making the server that will periodicly scrub * Config file for the scrubber. We make our own connection to the db here and bypass using the registry client so we don't have to expose non-public images over the http connection * make the commits * Add webob>=1.0.7 requirement to tools/pip-requires * all delayed deletes will be going through a new service, if delayed_delete is False, then delete it right away, otherwise set it to pending_delete * add scrub file * set the image to pending delete prior to scheduling the delete * refactor a bit so the db gets updated as needed and we only trigger the delay if the config option is set * add scheduled_delete_from_backend which delays the deletion of images for at least 1 second * don't delete directly but schedule deletion * add the api function to get the images that are pending deleteion * add in delayed delete options * Add workaround for Webob bug issue #12 and fix DELETE operation in S3 where URL parsing was broken * Add ability to create missing s3 bucket on first post, similar to Swift driver * Adding support for marker/limit query params from api, through registry client/api, and implementing at registry db api layer * Bug #787296: test_walk_versions fails with SQLalchemy 0.7 * OK, fixes the issue where older versions of webob.Request did not have the body_file_seekable attribute. After investigation, turned out that webob.Request.make_body_seekable() method was available in all versions of webob, so we use that instead * Added new disk_format type of 'iso'. Nova can use this information to identify images that have to be booted from a CDROM * adding marker & limit params to glance client * Auto-migrate if the tables don't exist yet * Fix up unit tests for S3 after note from Chris. Also fix bug when S3 test was skipped, was returning error by accident * * Adds functional test that works with Amazon S3 * Fixes parsing of "S3 URLs" which urlparse utterly barfs on because Amazon stupidly allows forward slashes in their secret keys * Update /etc/glance-api.conf for S3 settings * merging trunk, resolving conflicts * fixing sql query * completing marker functionality * Call stop_servers() for those 2 test cases missing it * Correct documentation * Add missing stop_servers() calls to two functional test cases * Remove changes to stub database * Auto-migrate if tables don't exist * Fix accidental delete * Remove additions to FIXTURES in test/stubs.py, which requried changes elsewhere * Sync with trunk * Documentation for new results filtering in the API and client * Fix tiny typo * Documentation for new results filtering in the API and client * Adding support for query filtering from the glance client library * renaming query_params to params * abstracting out filters query param serialization into BaseClient.do_request * renaming tests to resolve conflict * adding filters param to get_images and get_images_detailed in glance client * Bug #787296: test_walk_versions fails with SQLalchemy 0.7 * Updated doc with 'iso' disk_format * Update documentation * Adding support for api query filtering - equality testing on select attributes: name, status, container_format, disk_format - relative comparison of size attribute with size_min, size_max - equality testing on user-defined properties (preface property name with "property-" in query) * updating stubs with new sorting logic; updating tests * fixing some copy/paste errors * fixing some webob exceptions * slight modification to registry db api to ensure marker works correctly * slight refactoring per jaypipes' suggestions; sort on get images calls is now created_at desc * Add tests for 'iso' image type. Remove hard coding of next available image id in tests. This prevents new test images from being added to the set generated by tests.unit.stubs.FakeDatastore * pulling from parent branch * docstring fix * pushing marker/limit logic down into registry db api * adding support for marker & limit query params * removing some unnecessary imports * making registry db api filters more structured; adding in a bit of sqlalchemy code to filter image properties more efficiently * consolidating image_get_all_public and image_get_filtered in registry db api * adding test case for multiple parameters from command line * adding custom property api filtering * adding size_min and size_max api query filters * implemented api filtering on name, status, disk_format, and container_format * Adds versioning to the Glance API * Add test and fix for /v1.2/images not properly returning version choices * Add more tests for version URIs and accept headers and fix up some of Brian's review comments * Fix merge conflict.. * Changes versioned URIs to be /v1/ instead of /v1.0/ * Improve logging configuration docs.. * Doc and docstring fixes from Dan's review * Removed some test config files that slipped in.. * Fix up find_config_file() to accept an app_name arg. Update all documentation referencing config files * Fix pep8 complaint * Add DISK_FORMAT for 'iso' type images * Adds versioning to Glance's API * Changes glance index to return all public images in any status other than 'killed'. This should allow tools like euca-describe-images to show images while they are in a saving/untarring/decrypting state * Fix numbering in comment.. * Fixed doh. Updates test case to test for condition that should have failed with status!='active' * Changes glance index to return all public images in any status other than 'killed'. This should allow tools like euca-describe-images to show images while they are in a saving/untarring/decrypting state * Adding prefilled Authors, mailmap files Adding test to validate Authors file is properly set up * Documentation updates to make glance add command clearer, hopefully :) * adding Authors functionality; fixing one rogue pep8 violation * Improve logging configuration docs.. * Prevent users from uploading images with a bad or missing store. Allow deletion from registry when backend cannot be used * bcwaldon review fixups * adding comment * Fix for bug #768969: glance index shows non-active images; glance show does not show status * Completes the S3 storage backend. The original code did not actually fit the API from boto it turned out, and the stubs that were in the unit test were hiding this fact * catching NotFound to prevent failure on bad location * Prevent requests with invalid store in location param * Allow registry deletion to succeed if store deletion fails * Documentation updates to make glance add command clearer, hopefully :) * Fix for LP Bug #768969 * Expanding user confirmation default behavior * removing excessive exception handling * pep8 fixes * docstring and exception handling * Expanding user_confirm default behavior * I modified documentation to show more first-time user friendly examples on using glance. With the previous examples, I followed it as a first-time user and had to spend more than necessary time to figure out how to use it. With this modification, other first-time users would make it work on their systems more quickly * - Require user confirmation for "bin/glance clear" and "bin/glance delete " - Allow for override with -f/--force command-line option * adding --force option to test_add_clear * Adds a test case for updating an image's Name attribute. glance update was not regarding 'name' as a top-level modifiable attribute.. * Name is an attribute that is modifiable in glance update, too. * Mark image properties as deleted when deleting images. Added a unit test to verify public images and their properties get deleted when running a 'glance clear' command * Update tests and .bzrignore to use tests.sqlite instead of glance.sqlite * Only modify the connection URL in runs_sql if the original connection string starts with 'sqlite' * Create a decorator that handles setting the SQL store to a disk-based SQLite database when arbitrary SQL statements need to be run against the registry database during a test case * Docstring update on the run_sql_command function * Mark image properties as deleted when deleting images. Added a unit test to verify public images and their properties get deleted when running a 'glance clear' command * Add log_file to example glance.conf * fixing spacing in help text * adding confirmation on image delete/clear; adding user_confirm functionality * Add log_file to example glance.conf * Make sure we use get_option() when dealing with boolean values read from configuration files...otherwise "False" is True :( * Fixing tests. Sorry for late response * Make sure we use get_option() when dealing with boolean values read from configuration files...otherwise "False" is True :( * resolve merge conflicts * chnaged output * Open Diablo release * Diablo versioning * Fake merge with ancient trunk. This is only so that people who "accidentally" have been following lp:~hudson-openstack/glance/trunk will not have problems updating to this * Final versioning for Cactus * fixing after review * Removes capture of exception from eventlet in _upload_and_activate(), which catches the exceptions that come from the _safe_kill() method properly * RickH fixups from review * Add catch-all except: block in _upload() * change output from glance-registry * get latest from lp:glance * Ensures that configuration values for debug and verbose are used if command-line options are not set * Removes capture of exception from eventlet in _upload_and_activate(), which catches the exceptions that come from the _safe_kill() method properly * Fix logging in swift * Fix Thierry's notice about switched debug and verbose * Change parsing of headers to accept 'True', 'on', 1 for boolean truth values * Final cactus versioning * OK, fix docs to make it clear that only the string 'true' is allowed for boolean headers. Add False-hood unit tests as well * Logging was not being setup with configuration file values for debug/verbose * Fix up the way the exception is raised from _safe_kill()... When I "fixed" bug 729726, I mistakenly used the traceback as the message. doh * Change parsing of headers to accept 'True', 'on', 1 for boolean truth values * Add the migration sql scripts to MANIFEST.in. The gets them included in not only the tarball, but also by setup.py install * Add the migration sql scripts to MANIFEST.in. The gets them included in not only the tarball, but also by setup.py install * Changed raise of exception to avoid displaying incorrect error message in _safe_kill() * fix logging in swift * Changes "key" column in image_properties to "name" * Updated properties should be marked as deleted=0. This allows previously deleted properties to be reactivated on an update * Adds --config-file option to common options processing * Update the docs in bin/glance so that help for the 'update' command states that metadata not specified will be deleted * Fix config test fixtures and pep8 error in bin/glance-manage * Provide revised schema and migration scripts for turning 'size' column in 'images' table to BIGINT. This overcomes a 2 gig limit on images sizes that can be downloaded from Glance * Updated properties should be marked as deleted=0. Add unit tests * Use logging module, not echo, for logging SQLAlchemy. Fixes bug 746435 * Change order of setting debug/verbose logging. Thanks for spotting this, Elgar * Use logging module, not echo, for logging SQLAlchemy. Fixes bug 746435 * Ensure we don't ask the backend store to delete an image if the image is in a queued or saving state, since clearly the backend state has yet to completely store the image * Changes "key" column in image_properties to "name" * Use logging module, not echo for logging SQLAlchemy * Updates glance-manage to use configuration files as well as command line options * Ensure we don't ask a backend store to delete an image if the image is queued or saving * Moved migration into Python script, otherwise PostgreSQL was not migrated. Added changes to the functional test base class to reset the data store between tests. GLANCE_SQL_CONNECTION env variable is now GLANCE_TEST_SQL_CONNECTION * changed to more typical examples * Add migration scripts for revising the datatype of the 'size' column in the images table * Changes to database schema required to support images larger than 2Gig on MySQL. Does not update the migration scripts * Updates to the Registry API such that only external requests to update image properties purge existing properties. The update_image call now contains an extra flag to purge_props which is set to True for external requests but False internally * Updates to the Registry API such that only external requests to update image properties purge existing properties. The update_image call now contains an extra flag to purge_props which is set to True for external requests but False internally * Update the glance registry so that it marks properties as deleted if they are no longer exist when images are updated * Simple one.. just add back the Changelog I removed by accident in r94. Fixes bug #742353 * Adds checksumming to Glance * Uhhhm, stop_servers() should stop servers, not start them! Thanks to Cory for uncovering this copy/paste fail * Fix up test case after merging in bug fixes from trunk... expected results were incorrect in curl test * Add ChangeLog back to MANIFEST.in * Add migration testing and migration for disk_format/container_format * tests.unit.test_misc.execute -> tests.utils.execute after merge * Allow someone to set the GLANCE_TEST_MIGRATIONS_CONF environment variable to override the config file to run for the migrations unit test: * Update the glance registry so that it marks properties as deleted if they are no longer in the update list * Start eventlet WSGI server with a logger to avoid stdout output * Adds robust functional testing to Glance * Add migration script for checksum column * Fixed an oops. Didn't realized Repository.latest returned a 0-based version number, and forgot to reversed() the downgrade test * OK, migrations are finally under control and properly tested * Remove non-existing files from MANIFEST.in * Removed glance-combined. Fixed README * Removed glance-commit * Re-raise _safe_kill() exception in non-3-arg form to avoid pep8 deprecation error * Bug #737979: glance-control uses fixed path to Python interpreter, breaking virtualenv * Bug #737979: glance-control uses fixed path to Python interpreter, breaking virtualenv * Removes glance-combined and fixes TypeError from bad function calls in glance-manage * Start eventlet WSGI server with a logger to avoid stdout output * Pass boolean values to glance.client as strings, not integers * Small adjustment on wait_for_servers()... fixed infinite loop possibility * Adds robust functional testing to Glance * Ensure Content-type set to application/octet-stream for GET /images/ * Ensure Content-Length sent for GET /images/ * HTTPBackend.get() needed options in kwargs * Remove glance-combined (use glance-control all start). Fix glance-manage to call the setup_logging() and add_logging_options() methods according to the way they are called in glance-api and glance-registry * Support account:user:key in Swift URIs. Adds unit tests for various calls to parse_swift_tokens() * Adds documentation on configuring logging and a unit test for checking simple log output * Support account:user:key in Swift URIs. Adds unit tests for various calls to parse_swift_tokens() * Cherry pick r86 from bug720816 * Cherry pick r87 from bug720816 * Fixed run_tests.py addError() method since I noted it was faulty in another branch.. * Tiny pep8'ers * I stole the colorized code from nova * Fix typo * A quick patch to allow running the test suite on an alternate db backend * Merged trunk -resolved conflicts * [Add] colorization stolen from nova * Don't require swift module for unit-tests * Pep8 fix * Backing out unit-test workaround * Changed to have 2 slashes * Allow unit-tests to run without swift module * Remove spurios comment in test file * Add Glance CLI tool * Silly mistake when resolving merge conflict...fixed * Fixes passing of None values in metadata by turning them into strings. Also fixes the passing of the deleted column by converting it to and from a bool. The test for passing metadata was updated to include these values * Adds documentation on configuring logging and a test that log_file works. It didn't, so this also inludes fixes for setting up log handling :) * fix data passing * add failing test for None and deleted * Uses logger instead of logging in migration.py * Using logger in migration api instead of logging directly * Only clean up in the cleanup method. Also, we don't need the separate URI now * Use unregister_models instead of os.unlink to clean up after ourselves * Fixed unregister_models to actually work * Fixed migration test to use a second DB URL * Replaced use of has_key with get + default value * Make it clear that the checksum is an MD5 checksum in docs * Adds checksumming to Glance * Whoops! Left out a self.db_path * Allow tests to run on an alternate dburi given via environment variables * Adds ability for Swift to be used as a full-fledged backend. Adds POST/PUT capabilities to the SwiftBackend Adds lots of unit tests for both FilesystemBackend and SwiftBackend Removes now-unused tests.unit.fakeswifthttp module * Remove last vestiges of account in Swift store * Quick fixup on registry.get_client() * Public? => Public: per Cory's comment. Added a little more robust exception handling to some methods in bin/glance * Fixes for Devin and Rick's reviews * Adds disk_format and container_format to Image, and removes the type column * Fixes client update_image to work like create_image. Also fixes some messed up exceptions that were causing a try, except to reraise * Final review fixes. Makes disk_format and container_format optional. Makes glance-upload --type put the type in properties * remove test skip * Put account in glance.conf.sample's swift_store_auth_address, use real swift.common.client.ClientException, ensure tests work with older installed versions of Swift (which do not have, for example, swift.common.client.Connection.get_auth method) * Work around Eventlet exception clearing by memorizing exception context and re-raising using 3-arg form * Adds bin/glance to setup.py * Fixes from Rick's review #1 * Reverts Image `type` back to the old behavior of being nullable * Work around Eventlet exception clearing * Add sys.path mangling to glance-upload * Add sys.path adjustment magic to glance-upload * Adds ability for Swift to be used as a full-fledged backend. Adds POST/PUT capabilities to the SwiftBackend Adds lots of unit tests for both FilesystemBackend and SwiftBackend Removes now-unused tests.unit.fakeswifthttp module * Couple tiny cleanups noticed when readin merge diff. * bin/glance-admin => bin/glance, since it's really just the CLI tool to interact with Glance. Added lots of documentation and more logging statements in some critical areas (like the glance.registry calls.. * Adds lots of unit tests for verifying exceptions are raised properly with invalid or mismatched disk and container formats * Makes --kernel and --ramdisk required arguments for glance-upload since Nova currently requires them * Removing image_type required behavior * Removing requirement to pass kernel and ramdisk * Add test cases for missing and invalid disk and container formats * Requiring kernel and ramdisk args in glance-upload * Make disk_format and container_format required * Make disk_format and container_format required * Adds an admin tool to Glance (bin/glance-admin) that allows a user to administer the Glance server: * Make sure validate_image() doesn't throw exception on missing status when updating image * Adds disk_format and container_format to Image, and removes the type column * This adds a test case for LP Bug 704854 -- Exception raised by Registry server gets eaten by API server * Add debugging output to assert in test_misc. Trying to debug what Hudson fails on.. * Fixups from Rick's review * Removes now-unnecessary @validates decorator on model * I should probably rebase this commit considering all the previous commits weren't actually addressing the issue. The fact that I had glance-api and glance-registry installed on my local machine was causing the test runs to improperly return a passing result * Use Nova's path trick in all bins.. * Add path to glance-control * Removes image type validation in the Glance registry * Adding vhd as recognized image type * Reverting the removal of validation * Removing image type validation * Adds --pid-file option to bin/glance-control * Add %default for image type in glance-upload * Adds Location: header to return from API server for POST /images, per APP spec * Cleanups from Soren's review * Add an ImportError check when importing migrate.exceptions, as the location of that module changed in a recent version of the sqlalchemy-migrate library * Adds Location: header to return from API server for POST /images, per APP spec * This adds a test case for LP Bug 704854 -- Exception raised by Registry server gets eaten by API server * Adds --pid-file option to bin/glance-control * Add an ImportError check when importing migrate.exceptions, as the location of that module changed in a recent version of the sqlalchemy-migrate library * Adds sql_idle_timeout to reestablish connections to database after given period of time * Add sql_idle_timeout * Removes lockfile and custom python-daemon server initialization in favour of paste.deploy * Review 3 fixups * Remove get_config_file_options() from glance-control * Fixes for Rick review #2 * Remove no-longer-needed imports.. * Remove extraneous debug import.. * Changes the server daemon programs to be configured only via paste.deploy configuration files. Removed ability to configure server options from CLI options when starting the servers with the exception of --verbose and --debug, which are useful during debugging * Adds glance-combined and glance-manage to setup.py * Fix merge conflicts * Adds glance-combined and glance-manage to setup.py * Fixes bug 714454 * ReStructure Text files need to end in .rst, not .py ;) * Update README, remove some vestigial directories, and other small tweaks * Removing dubious advice * Adds facilities for configuring Glance's servers via configuration files * Use fix_path on find_config_file() too * Fixups from Rick's review * Including tests/ in pep8 * Typo fixes, clarifying * Updating README, rmdir some empty dirs * Adds bin/glance-control program server daemonization wrapper program based on Swift's swift-init script * Ignore build and deploy-related files * Adds sqlalchemy migrations * Fix bug 712575. Make BASE = models.BASE * Make sure BASE is the models.BASE, not a new declarative_base() object * Had to reverse search order of directories for finding config files * Removes lockfile and custom python-daemon server initialization in favour of paste.deploy * Adds facilities for configuring Glance's servers via configuration files * Creating indexes * Adding migration test * Fixing migration import errors * Small cleanups * glance-manage uses common options * Merging in glance/cactus * Pep8 fix * Pep8 fixes * Refactoring into option groups * Hopefully-final versioning (0.1.7), no review needed * Final versioning, no review needed * Adding db_sync to mirror nova * Adding some basic documentation * Better logging * Adding image_properties migration * Adding migration for images table * Adding migration management commands * Remove debugging output that wasn't supposed to go into this branch (yet) :) * Adds --debug option for DEBUG-level logging. --verbose now only outputs INFO-level log records * Typo add_option -> add_options * Fixes from Rick's review. Thanks, Rick * Adds --sql-connection option * First round of logging functionality: * Merged use-optparse * Removes glance.common.db.sqlalchemy and moves registration of models and create_engine into glance.registry.db.api * pep8-er in bin/glance-combined * Fixes lp710789 - use-optparse breaks daemonized process stop * Adds bin/glance-combined. Useful in testing.. * Tiny pep8 fixup in setup.py * Rework what comes back from parse_options()[0] to not stringify option values. Keep them typed * Remove use of gflags entirely. Use optparse * Removing unecessary param to get_all_public * Merging trunk * Adding back some missing code * Cleaning up some code * Makes Glance's versioning non-static. Uses Nova's versioning scheme * Adds/updates the copyright info on most of the files in glance and copies over the Authors check from Nova * Removing sqlalchemy dir * Removed methods from sqlalchemy/api * Refactor update/create * Messed up a permission somehow * Refactoring destroy * feh * A few more * A few more I missed * version bumped after tarball cut. no review needed.. * Bump version * Removing authors test for now * PEP8 cleanup * PEP8 cleanup * Should fix the sphinx issue * Adds architecture docs and enables Graphviz sphinx extension. Also cleans up source code formatting in docs * Make sphinx conditional * bumps version after tarball release of 0.1.4 * Bump version * Added bzr to pip-requires and refixed some pep8 stuff * Authors check * A few more copyrights * Copyright year change * Pylint cleanup * Added copyright info * Adds architecture docs and enables Graphviz sphinx extension. Also cleans up source code formatting in docs * bumps release version. ready for Bexar final release * Version bump after release * added sphinx and argparse into tools/pip-requires so that setup.py works. this bug also prevents nova from creating a virtualenv * fixes setup install pip dependencies * Version bump for release * Fixes bug #706636: Make sure pep8 failures will return failure for run_tests.sh * Make run_tests.sh return failure when pep8 returns fail, and fix the pep8 error in /bin/glance-upload * This patch: * Converts dashes to underscores when extracting image-properties from HTTP headers (we already do this for 'regular' image attributes * Update image_properties on image PUTs rather than trying to create dups * This patch replaces some remaining references to req.body (which buffers the entire request body into memory!) with the util.has_body method which can determine whether a body is present without reading any of it into memory * Adding Apache license, fixing long line * Making glance-upload a first-class binary * Revove useless test_data.py file, add image uploader * Fix property create * Dont buffer entire image stream on PUT * Adds man pages for glance-registry and glance-api programs. Adds Getting Started guide to the Glance documentation * Fixes LP Bug #700162: Images greater than 2GB cannot be uploaded using glance.client.Client * Duh, it helps to import the class you are inheriting from... * OK, found a solution to our test or functional dilemma. w00t * Make compat with chunked transfer * Removes the last vestiges of Twisted from Glance * Pull in typo fix * Add in manpage installation hook. Thanks Soren :) * Fixes LP Bug #700162: Images greater than 2GB cannot be uploaded using glance.client.Client * Removes Twisted from tools/install_venv.py and zope.interface from tools/pip-requires. Shaved a full 45 seconds for me off of run_tests.sh -V -f now we're not downloading a giant Twisted tarball.. * Remove last little vestiges of twisted * Quick typo fix in docs * Add run_tests.py to tarball * Also include run_tests.py in tarball * Adds man pages for glance-registry and glance-api. Adds Getting Started guide to Glance docs * Fixes bug #696375: x-image-meta-size not optional despite documentation saying so * PEP8 fixes in /glance/store/__init__.py * Fix Bug #704038: Unable to start or connect to register server on anything other than 0.0.0.0:9191 * Fix Bug #704038: Unable to start or connect to register server on anything other than 0.0.0.0:9191 * upgrade version.. * Fixes Bug#696375: x-image-meta-size is not optional, contrary to documentation * Increase version after release * Cut 0.1.2 * Files missing from the tarball (and you probably need to cut a 0.1.2.) * Cleanup of RST documentation and addition of docs on an image's status * Include some files that were left out * Implements the S3 store to the level of the swift store * fixes bug698318 * Fixes suggested by JayPipes review. Did not modify docstrings in non-related files * This merge is in conjunction with lp:~rconradharris/nova/xs-snap-return-image-id-before-snapshot * Updating docs * Merging trunk * Clean up the rest of Glance's PEP8 problems * PEP-8 Fixes * Fixing eventlet-raise issue * Bug #698316: Glance reads the whole image into memory when handling a POST /images request * Merging trunk * Fixed pylint/pep8 for glance.store.s3 * Implement S3 to the level of swift * removing old methods * refactoring so update can take image_data * More PEP8 fixes * Fix all Glance's pep8 problems * Remove incorrect doccomments about there being a default for the host parameter, fix misdocumented default port, and remove handling of missing parameters in BaseClient, because the values are always specified by the subclass's __init__ * Bug #696385: Glance is not pep8-clean * Bug #696382: Glance client parameter defaults misdocumented * Fixes a number of things that came up during initial coding of the admin tool: * Made review changes from Rick * Duh, use_ssl should not use HTTPConnection.. * Remove final debugging statement * merge trunk * Remove debugging statements * Fixes a number of things that came up during initial coding of the admin tool: * fix bug 694382 * Bug #694382: setup.py refers to parallax-server and teller-server, when these have been renamed * documentation cleanup and matching to other OpenStack projects. Glance is no longer the red-headed documentation stepchild in OpenStack.. * Converts timestamp attributes to datetime objects before persisting * Adding __protected_attributes__, some PEP8 cleanups * review fixes * Update sphinx conf to match other OpenStack projects * Documentation cleanup. Splits out index.rst into multiple section docs * Converting to datetime before saving image * Enhances POST /images call to, you know, actually make it work.. * Make directory for filesystem backend * doing the merge of this again...somehow the trunk branch never got rev26 :( * Adds POST /images work that saves image data to a store backend * Update docs for adding image.. * Fix Chris minor nit on docstring * Fixes binaries, updates WSGI file to more recent version from Nova, and fixes an issue in SQLAlchemy API that was being hidden by stubs and only showed up when starting up the actual binaries and testing.. * Major refactoring.. * Fix testing/debug left in * Fixes from review * Documentation updates and GlanceClient -> Client * Refactor a bunch of stuff around the image files collection * Cleanup around x-image-meta and x-image-meta-property HTTP headers in GET/HEAD * Update /glance/client.py to have GlanceClient do all operations that RegistryClient does * Merges Glance API with the registry API: * Makes HEAD /images/ return metadata in headers * Make GET /images/ return image data with metadata in headers Updates docs some (more needed) * Second step in simplifying the Glance API * This is the first part of simplifying the Glance API and consolidating the Teller and Parallax APIs into a single, unified Glance API * Adds DELETE call to Teller API * Fixes Swift URL Parsing in Python 2.6.5 by adding back netloc * Moving imports into main which will only be executed after we daemonize thus avoiding the premature initialization of epoll * Delaying eventlet import until after daemonization * Fix Swift URL parsing for Python 2.6.5 * Don't leak implementation details in Swift backend. Return None on successful delete_object call * Adds call to Swift's DELETE * Typo fixed and tiny cleanups * Adds DELETE to Teller's API * Just some small cleanups, fixing: * Swapped port numbers (Parallax Port <=> Teller port) * Removing extraneous routes in Teller API * Adding required slashes to do_request * * Changes Teller API to use REST with opaque ID sent in API calls instead of a "parallax URI". This hides the URI stuff behind the API layer in communication between Parallax and Teller. * Adds unit tests for the only complete Teller API call so far: GET images/, which returns a gzip'd string of image data * Fixing swapped port numbers, removing extraneous routes in Teller controller, adding required slash for do_request calls * * Changes Teller API to use REST with opaque ID sent in API calls instead of a "parallax URI". This hides the URI stuff behind the API layer in communication between Parallax and Teller. * Adds unit tests for the only complete Teller API call so far: GET images/, which returns a gzip'd string of image data * Add files attribute to Parallax client tests * Adds client classes for Parallax and Teller and fixes some issues where our controller was not returning proper HTTP response codes on errors.. * Cleanup/fixes for Rick review * Adds client classes ParallaxClient and (stubbed) TellerClient to new glance.client module * packaging fixups preparing for release candidate * Remove symlinks in bin/ * Packaging fixups * awesomeness. merging into trunk since my parallax-api is already in trunk I believe. :) * Moving ATTR helpers into db module * PUTing and POSTing using image key * Quick fix...gives base Model an update() method to make it behave like a dict * Make returned mapping have an 'image' key to help in XML serialization * Ignore virtualenv directory in bzr * This patch removes unique index on the 'key' column of image_metadatum and replaces it with a compound UniqueConstraint on 'image_id' and 'key'. The 'key' column remains indexed * Fixes lp653358 * Renaming is_cloudfiles_available -> is_swift_available * Adds compound unique constraint to ImageMetadatum * Using swift.common.client rather than python-cloudfiles in Teller's Swift backend * Adds DELETE to the Parallax REST API * Implements the REST call for updating image metadata in the Parallax API * Implements Parallax API call to register a new image * Adds a /images/detail route to the Parallax controller, adds a unit test for it, and cleans up Michael's suggestions * Works around non-RFC compliance in Python (< 2.6.5) urlparse library * Workaround for bug in Python 2.6.1 urlparse library * Adds tests for bad status set on image * Implements Parallax API call to register a new image * This patch overhauls the testing in Glance: * unittest2 -> unittest. For now, since not using unittest2 features yet * Fixes up test_teller_api.py to use stubout correctly. Fixes a few bugs that showed up in the process, and remove the now-unnecessary FakeParallaxAdapter * First round of cleaning up the unittests. Adds test suite runner, support for virtualenv setup and library dependencies, resolves issues with ImportErrors on cloudfiles, adds pymox/stubout support and splits the backend testing into distinct unittest cases * With this patch Parallax and teller now work end-to-end with the Swift backend * Adding missing backend files, fixing typos in comments * This patch: * Decouples Controller for ParallaxAdapter implementation by adding generic RegistryAdapter and providing a lookup function * Adds base model attributes to Parallax's JSON (created_at, etc) * Improving symmetry between teller and parallax * Fixing swift authurl * Add RegistryAdapter, include ModelBase attributes * Fixing Teller image tests * Created teller-server.py in bin/ * Cleaning up Teller backend * Rewrote ImageController to inherit from the work Rick Harris did in glance.common. Moved it into teller/api/images.py to make teller match parallax. Fixed tests. Renamed them to distinguish if any parallax tests ever get written * Adding Image index call, nesting the Image show dict to facilitate XML serialization * Moving parallax models out of common and into the parallax module * Updated tests * Reimplements server.py as a wsgi api inheriting from glance.common * This patch: * pulls in a number of useful libraries from Nova under the common/ path (we can factor those out to a shared library in Bexar-release) * Defines the models in common.db.sqlalchemy.models.py (this should be factored out into the parallax package soon) * Adds the parallax api-server under /bin (if PyPI was used to pull python-daemon and python-lockfile, you may need to apply a patch I have against it) * Changes the obj['uri'] to obj['location'] to better sync with the representation within Nova. Adds the image_lookup_fn = ParallaxAdapter.lookup to teller.server * ImageChunk -> ImageFile, merging APIRouter into API for now * Adding Apache header to test_data.py * Small cleanups * Parallax will return obj['location'] instead of obj['uri'], also maybe a parallax lookup fn would be nice? * Implements a Parallax adapter for looking up images requested from nova. Adds a size check to SwiftBackend to ensure that the chunks haven't been truncated or anything * Reconciling parallax modifications with modulization of glance * Adding Images controller * Adding API directory and server.py * Modulify the imports * Implements Parallax adapter for lookups from Teller, also adds size expectations to the backend adapters * Adding files from Nova * Makes glance a module, containing teller and parallax sub-modules * libify glance into teller and parallax modules. Make nosetests work by making tests and tests/unit/ into packages * Rearranged the code a little. Added a setup.py. Added sphinx doc skeleton * Added setup.py and sphinx docs * Reorg to make Monty's build pedanticness side happier * Implements Swift backend for teller * ignore all .pyc files * Merging ricks changes * Adding basic image controller and mock backends * Adding description of registry data structure * Adding teller_server * adding filesystem and http backends * Initial check-in glance-2014.1/doc/0000775000175400017540000000000012323736427014746 5ustar jenkinsjenkins00000000000000glance-2014.1/doc/source/0000775000175400017540000000000012323736427016246 5ustar jenkinsjenkins00000000000000glance-2014.1/doc/source/cache.rst0000664000175400017540000001244412323736226020045 0ustar jenkinsjenkins00000000000000.. Copyright 2011 OpenStack Foundation All Rights Reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. The Glance Image Cache ====================== The Glance API server may be configured to have an optional local image cache. A local image cache stores a copy of image files, essentially enabling multiple API servers to serve the same image file, resulting in an increase in scalability due to an increased number of endpoints serving an image file. This local image cache is transparent to the end user -- in other words, the end user doesn't know that the Glance API is streaming an image file from its local cache or from the actual backend storage system. Managing the Glance Image Cache ------------------------------- While image files are automatically placed in the image cache on successful requests to ``GET /images/``, the image cache is not automatically managed. Here, we describe the basics of how to manage the local image cache on Glance API servers and how to automate this cache management. Controlling the Growth of the Image Cache ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The image cache has a configurable maximum size (the ``image_cache_max_size`` configuration file option. However, when images are successfully returned from a call to ``GET /images/``, the image cache automatically writes the image file to its cache, regardless of whether the resulting write would make the image cache's size exceed the value of ``image_cache_max_size``. In order to keep the image cache at or below this maximum cache size, you need to run the ``glance-cache-pruner`` executable. The recommended practice is to use ``cron`` to fire ``glance-cache-pruner`` at a regular interval. Cleaning the Image Cache ~~~~~~~~~~~~~~~~~~~~~~~~ Over time, the image cache can accumulate image files that are either in a stalled or invalid state. Stalled image files are the result of an image cache write failing to complete. Invalid image files are the result of an image file not being written properly to disk. To remove these types of files, you run the ``glance-cache-cleaner`` executable. The recommended practice is to use ``cron`` to fire ``glance-cache-cleaner`` at a semi-regular interval. Prefetching Images into the Image Cache ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Some installations have base (sometimes called "golden") images that are very commonly used to boot virtual machines. When spinning up a new API server, administrators may wish to prefetch these image files into the local image cache to ensure that reads of those popular image files come from a local cache. To queue an image for prefetching, you can use one of the following methods: * If the ``cache_manage`` middleware is enabled in the application pipeline, you may call ``PUT /queued-images/`` to queue the image with identifier ```` Alternately, you can use the ``glance-cache-manage`` program to queue the image. This program may be run from a different host than the host containing the image cache. Example usage:: $> glance-cache-manage --host= queue-image This will queue the image with identifier ```` for prefetching Once you have queued the images you wish to prefetch, call the ``glance-cache-prefetcher`` executable, which will prefetch all queued images concurrently, logging the results of the fetch for each image. Finding Which Images are in the Image Cache ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ You can find out which images are in the image cache using one of the following methods: * If the ``cachemanage`` middleware is enabled in the application pipeline, you may call ``GET /cached-images`` to see a JSON-serialized list of mappings that show cached images, the number of cache hits on each image, the size of the image, and the times they were last accessed. Alternately, you can use the ``glance-cache-manage`` program. This program may be run from a different host than the host containing the image cache. Example usage:: $> glance-cache-manage --host= list-cached * You can issue the following call on \*nix systems (on the host that contains the image cache):: $> ls -lhR $IMAGE_CACHE_DIR where ``$IMAGE_CACHE_DIR`` is the value of the ``image_cache_dir`` configuration variable. Note that the image's cache hit is not shown using this method. Manually Removing Images from the Image Cache ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ If the ``cachemanage`` middleware is enabled, you may call ``DELETE /cached-images/`` to remove the image file for image with identifier ```` from the cache. Alternately, you can use the ``glance-cache-manage`` program. Example usage:: $> glance-cache-manage --host= delete-cached-image glance-2014.1/doc/source/formats.rst0000664000175400017540000000577312323736226020464 0ustar jenkinsjenkins00000000000000.. Copyright 2011 OpenStack Foundation All Rights Reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Disk and Container Formats ========================== When adding an image to Glance, you must specify what the virtual machine image's *disk format* and *container format* are. Disk and container formats are configurable on a per-deployment basis. This document intends to establish a global convention for what specific values of *disk_format* and *container_format* mean. Disk Format ----------- The disk format of a virtual machine image is the format of the underlying disk image. Virtual appliance vendors have different formats for laying out the information contained in a virtual machine disk image. You can set your image's disk format to one of the following: * **raw** This is an unstructured disk image format * **vhd** This is the VHD disk format, a common disk format used by virtual machine monitors from VMWare, Xen, Microsoft, VirtualBox, and others * **vmdk** Another common disk format supported by many common virtual machine monitors * **vdi** A disk format supported by VirtualBox virtual machine monitor and the QEMU emulator * **iso** An archive format for the data contents of an optical disc (e.g. CDROM). * **qcow2** A disk format supported by the QEMU emulator that can expand dynamically and supports Copy on Write * **aki** This indicates what is stored in Glance is an Amazon kernel image * **ari** This indicates what is stored in Glance is an Amazon ramdisk image * **ami** This indicates what is stored in Glance is an Amazon machine image Container Format ---------------- The container format refers to whether the virtual machine image is in a file format that also contains metadata about the actual virtual machine. Note that the container format string is not currently used by Glance or other OpenStack components, so it is safe to simply specify **bare** as the container format if you are unsure. You can set your image's container format to one of the following: * **bare** This indicates there is no container or metadata envelope for the image * **ovf** This is the OVF container format * **aki** This indicates what is stored in Glance is an Amazon kernel image * **ari** This indicates what is stored in Glance is an Amazon ramdisk image * **ami** This indicates what is stored in Glance is an Amazon machine image * **ova** This indicates what is stored in Glance is an OVA tar archive file glance-2014.1/doc/source/controllingservers.rst0000664000175400017540000002640212323736226022745 0ustar jenkinsjenkins00000000000000.. Copyright 2011 OpenStack Foundation All Rights Reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Controlling Glance Servers ========================== This section describes the ways to start, stop, and reload Glance's server programs. Starting a server ----------------- There are two ways to start a Glance server (either the API server or the registry server): * Manually calling the server program * Using the ``glance-control`` server daemon wrapper program We recommend using the second method. Manually starting the server ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The first is by directly calling the server program, passing in command-line options and a single argument for a ``paste.deploy`` configuration file to use when configuring the server application. .. note:: Glance ships with an ``etc/`` directory that contains sample ``paste.deploy`` configuration files that you can copy to a standard configuation directory and adapt for your own uses. Specifically, bind_host must be set properly. If you do `not` specifiy a configuration file on the command line, Glance will do its best to locate a configuration file in one of the following directories, stopping at the first config file it finds: * ``$CWD`` * ``~/.glance`` * ``~/`` * ``/etc/glance`` * ``/etc`` The filename that is searched for depends on the server application name. So, if you are starting up the API server, ``glance-api.conf`` is searched for, otherwise ``glance-registry.conf``. If no configuration file is found, you will see an error, like:: $> glance-api ERROR: Unable to locate any configuration file. Cannot load application glance-api Here is an example showing how you can manually start the ``glance-api`` server and ``glance-registry`` in a shell.:: $ sudo glance-api glance-api.conf --debug & jsuh@mc-ats1:~$ 2011-04-13 14:50:12 DEBUG [glance-api] ******************************************************************************** 2011-04-13 14:50:12 DEBUG [glance-api] Configuration options gathered from config file: 2011-04-13 14:50:12 DEBUG [glance-api] /home/jsuh/glance-api.conf 2011-04-13 14:50:12 DEBUG [glance-api] ================================================ 2011-04-13 14:50:12 DEBUG [glance-api] bind_host 65.114.169.29 2011-04-13 14:50:12 DEBUG [glance-api] bind_port 9292 2011-04-13 14:50:12 DEBUG [glance-api] debug True 2011-04-13 14:50:12 DEBUG [glance-api] default_store file 2011-04-13 14:50:12 DEBUG [glance-api] filesystem_store_datadir /home/jsuh/images/ 2011-04-13 14:50:12 DEBUG [glance-api] registry_host 65.114.169.29 2011-04-13 14:50:12 DEBUG [glance-api] registry_port 9191 2011-04-13 14:50:12 DEBUG [glance-api] verbose False 2011-04-13 14:50:12 DEBUG [glance-api] ******************************************************************************** 2011-04-13 14:50:12 DEBUG [routes.middleware] Initialized with method overriding = True, and path info altering = True 2011-04-13 14:50:12 DEBUG [eventlet.wsgi.server] (21354) wsgi starting up on http://65.114.169.29:9292/ $ sudo glance-registry glance-registry.conf & jsuh@mc-ats1:~$ 2011-04-13 14:51:16 INFO [sqlalchemy.engine.base.Engine.0x...feac] PRAGMA table_info("images") 2011-04-13 14:51:16 INFO [sqlalchemy.engine.base.Engine.0x...feac] () 2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Col ('cid', 'name', 'type', 'notnull', 'dflt_value', 'pk') 2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (0, u'created_at', u'DATETIME', 1, None, 0) 2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (1, u'updated_at', u'DATETIME', 0, None, 0) 2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (2, u'deleted_at', u'DATETIME', 0, None, 0) 2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (3, u'deleted', u'BOOLEAN', 1, None, 0) 2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (4, u'id', u'INTEGER', 1, None, 1) 2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (5, u'name', u'VARCHAR(255)', 0, None, 0) 2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (6, u'disk_format', u'VARCHAR(20)', 0, None, 0) 2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (7, u'container_format', u'VARCHAR(20)', 0, None, 0) 2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (8, u'size', u'INTEGER', 0, None, 0) 2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (9, u'status', u'VARCHAR(30)', 1, None, 0) 2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (10, u'is_public', u'BOOLEAN', 1, None, 0) 2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (11, u'location', u'TEXT', 0, None, 0) 2011-04-13 14:51:16 INFO [sqlalchemy.engine.base.Engine.0x...feac] PRAGMA table_info("image_properties") 2011-04-13 14:51:16 INFO [sqlalchemy.engine.base.Engine.0x...feac] () 2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Col ('cid', 'name', 'type', 'notnull', 'dflt_value', 'pk') 2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (0, u'created_at', u'DATETIME', 1, None, 0) 2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (1, u'updated_at', u'DATETIME', 0, None, 0) 2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (2, u'deleted_at', u'DATETIME', 0, None, 0) 2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (3, u'deleted', u'BOOLEAN', 1, None, 0) 2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (4, u'id', u'INTEGER', 1, None, 1) 2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (5, u'image_id', u'INTEGER', 1, None, 0) 2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (6, u'key', u'VARCHAR(255)', 1, None, 0) 2011-04-13 14:51:16 DEBUG [sqlalchemy.engine.base.Engine.0x...feac] Row (7, u'value', u'TEXT', 0, None, 0) $ ps aux | grep glance root 20009 0.7 0.1 12744 9148 pts/1 S 12:47 0:00 /usr/bin/python /usr/bin/glance-api glance-api.conf --debug root 20012 2.0 0.1 25188 13356 pts/1 S 12:47 0:00 /usr/bin/python /usr/bin/glance-registry glance-registry.conf jsuh 20017 0.0 0.0 3368 744 pts/1 S+ 12:47 0:00 grep glance Simply supply the configuration file as the first argument (the ``etc/glance-api.conf`` and ``etc/glance-registry.conf`` sample configuration files were used in the above example) and then any common options you want to use (``--debug`` was used above to show some of the debugging output that the server shows when starting up. Call the server program with ``--help`` to see all available options you can specify on the command line.) For more information on configuring the server via the ``paste.deploy`` configuration files, see the section entitled :doc:`Configuring Glance servers ` Note that the server `daemonizes` itself by using the standard shell backgrounding indicator, ``&``, in the previous example. For most use cases, we recommend using the ``glance-control`` server daemon wrapper for daemonizing. See below for more details on daemonization with ``glance-control``. Using the ``glance-control`` program to start the server ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The second way to start up a Glance server is to use the ``glance-control`` program. ``glance-control`` is a wrapper script that allows the user to start, stop, restart, and reload the other Glance server programs in a fashion that is more conducive to automation and scripting. Servers started via the ``glance-control`` program are always `daemonized`, meaning that the server program process runs in the background. To start a Glance server with ``glance-control``, simply call ``glance-control`` with a server and the word "start", followed by any command-line options you wish to provide. Start the server with ``glance-control`` in the following way:: $> sudo glance-control [OPTIONS] start [CONFPATH] .. note:: You must use the ``sudo`` program to run ``glance-control`` currently, as the pid files for the server programs are written to /var/run/glance/ Here is an example that shows how to start the ``glance-registry`` server with the ``glance-control`` wrapper script. :: $ sudo glance-control api start glance-api.conf Starting glance-api with /home/jsuh/glance.conf $ sudo glance-control registry start glance-registry.conf Starting glance-registry with /home/jsuh/glance.conf $ ps aux | grep glance root 20038 4.0 0.1 12728 9116 ? Ss 12:51 0:00 /usr/bin/python /usr/bin/glance-api /home/jsuh/glance-api.conf root 20039 6.0 0.1 25188 13356 ? Ss 12:51 0:00 /usr/bin/python /usr/bin/glance-registry /home/jsuh/glance-registry.conf jsuh 20042 0.0 0.0 3368 744 pts/1 S+ 12:51 0:00 grep glance The same configuration files are used by ``glance-control`` to start the Glance server programs, and you can specify (as the example above shows) a configuration file when starting the server. In order for your launched glance service to be monitored for unexpected death and respawned if necessary, use the following option: $ sudo glance-control [service] start --respawn ... Note that this will cause ``glance-control`` itself to remain running. Also note that deliberately stopped services are not respawned, neither are rapidly bouncing services (where process death occurred within one second of the last launch). By default, output from glance services is discarded when launched with ``glance-control``. In order to capture such output via syslog, use the following option: $ sudo glance-control --capture-output ... Stopping a server ----------------- If you started a Glance server manually and did not use the ``&`` backgrounding function, simply send a terminate signal to the server process by typing ``Ctrl-C`` If you started the Glance server using the ``glance-control`` program, you can use the ``glance-control`` program to stop it. Simply do the following:: $> sudo glance-control stop as this example shows:: $> sudo glance-control registry stop Stopping glance-registry pid: 17602 signal: 15 Restarting a server ------------------- You can restart a server with the ``glance-control`` program, as demonstrated here:: $> sudo glance-control registry restart etc/glance-registry.conf Stopping glance-registry pid: 17611 signal: 15 Starting glance-registry with /home/jpipes/repos/glance/trunk/etc/glance-registry.conf glance-2014.1/doc/source/identifiers.rst0000664000175400017540000000201412323736226021277 0ustar jenkinsjenkins00000000000000.. Copyright 2010 OpenStack Foundation All Rights Reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Image Identifiers ================= Images are uniquely identified by way of a URI that matches the following signature:: /v1/images/ where `` is the resource location of the Glance service that knows about an image, and `` is the image's identifier. Image identifiers in Glance are *uuids*, making them *globally unique*. glance-2014.1/doc/source/policies.rst0000664000175400017540000001005112323736226020601 0ustar jenkinsjenkins00000000000000.. Copyright 2012 OpenStack Foundation All Rights Reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Policies ======== Glance's public API calls may be restricted to certain sets of users using a policy configuration file. This document explains exactly how policies are configured and what they apply to. A policy is composed of a set of rules that are used by the policy "Brain" in determining if a particular action may be performed by the authorized tenant. Constructing a Policy Configuration File ---------------------------------------- A policy configuration file is a simply JSON object that contain sets of rules. Each top-level key is the name of a rule. Each rule is a string that describes an action that may be performed in the Glance API. The actions that may have a rule enforced on them are: * ``get_images`` - List available image entities * ``GET /v1/images`` * ``GET /v1/images/detail`` * ``GET /v2/images`` * ``get_image`` - Retrieve a specific image entity * ``HEAD /v1/images/`` * ``GET /v1/images/`` * ``GET /v2/images/`` * ``download_image`` - Download binary image data * ``GET /v1/images/`` * ``GET /v2/images//file`` * ``upload_image`` - Upload binary image data * ``POST /v1/images`` * ``PUT /v1/images/`` * ``PUT /v2/images//file`` * ``copy_from`` - Copy binary image data from URL * ``POST /v1/images`` * ``PUT /v1/images/`` * ``add_image`` - Create an image entity * ``POST /v1/images`` * ``POST /v2/images`` * ``modify_image`` - Update an image entity * ``PUT /v1/images/`` * ``PUT /v2/images/`` * ``publicize_image`` - Create or update images with attribute * ``POST /v1/images`` with attribute ``is_public`` = ``true`` * ``PUT /v1/images/`` with attribute ``is_public`` = ``true`` * ``POST /v2/images`` with attribute ``visibility`` = ``public`` * ``PUT /v2/images/`` with attribute ``visibility`` = ``public`` * ``delete_image`` - Delete an image entity and associated binary data * ``DELETE /v1/images/`` * ``DELETE /v2/images/`` * ``add_member`` - Add a membership to the member repo of an image * ``POST /v2/images//members`` * ``get_members`` - List the members of an image * ``GET /v1/images//members`` * ``GET /v2/images//members`` * ``delete_member`` - Delete a membership of an image * ``DELETE /v1/images//members/`` * ``DELETE /v2/images//members/`` * ``modify_member`` - Create or update the membership of an image * ``PUT /v1/images//members/`` * ``PUT /v1/images//members`` * ``POST /v2/images//members`` * ``PUT /v2/images//members/`` * ``manage_image_cache`` - Allowed to use the image cache management API To limit an action to a particular role or roles, you list the roles like so :: { "delete_image": ["role:admin", "role:superuser"] } The above would add a rule that only allowed users that had roles of either "admin" or "superuser" to delete an image. Examples -------- Example 1. (The default policy configuration) :: { "default": [] } Note that an empty JSON list means that all methods of the Glance API are callable by anyone. Example 2. Disallow modification calls to non-admins :: { "default": [], "add_image": ["role:admin"], "modify_image": ["role:admin"], "delete_image": ["role:admin"] } glance-2014.1/doc/source/common-image-properties.rst0000664000175400017540000000343712323736226023546 0ustar jenkinsjenkins00000000000000.. Copyright 2013 OpenStack Foundation All Rights Reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Common Image Properties ======================= When adding an image to Glance, you may specify some common image properties that may prove useful to consumers of your image. This document explains the names of these properties and the expected values. The common image properties are also described in a JSON schema, found in etc/schema-image.json in the Glance source code. **architecture** ---------------- Operating system architecture as specified in http://docs.openstack.org/trunk/openstack-compute/admin/content/adding-images.html **instance_uuid** ----------------- The ID of the instance used to create this image. **kernel_id** ------------- The ID of image stored in Glance that should be used as the kernel when booting an AMI-style image. **ramdisk_id** -------------- The ID of image stored in Glance that should be used as the ramdisk when booting an AMI-style image. **os_distro** ------------- The common name of the operating system distribution as specified in http://docs.openstack.org/trunk/openstack-compute/admin/content/adding-images.html **os_version** -------------- The operating system version as specified by the distributor. glance-2014.1/doc/source/glanceclient.rst0000664000175400017540000000210612323736226021424 0ustar jenkinsjenkins00000000000000.. Copyright 2011-2012 OpenStack Foundation All Rights Reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Using Glance's Client Tools =========================== The command-line tool and python library for Glance are both installed through the python-glanceclient project. Explore the following resources for more information: * `Official Docs `_ * `Pypi Page `_ * `GitHub Project `_ glance-2014.1/doc/source/conf.py0000664000175400017540000002141112323736226017541 0ustar jenkinsjenkins00000000000000# -*- coding: utf-8 -*- # Copyright (c) 2010 OpenStack Foundation. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # implied. # See the License for the specific language governing permissions and # limitations under the License. # # Glance documentation build configuration file, created by # sphinx-quickstart on Tue May 18 13:50:15 2010. # # This file is execfile()'d with the current directory set to its containing # dir. # # Note that not all possible configuration values are present in this # autogenerated file. # # All configuration values have a default; values that are commented out # serve to show the default. import os import sys # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. sys.path = [ os.path.abspath('../..'), os.path.abspath('../../bin') ] + sys.path # -- General configuration --------------------------------------------------- # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = ['sphinx.ext.coverage', 'sphinx.ext.ifconfig', 'sphinx.ext.intersphinx', 'sphinx.ext.pngmath', 'sphinx.ext.graphviz', 'oslosphinx', ] # Add any paths that contain templates here, relative to this directory. # templates_path = [] # The suffix of source filenames. source_suffix = '.rst' # The encoding of source files. #source_encoding = 'utf-8' # The master toctree document. master_doc = 'index' # General information about the project. project = u'Glance' copyright = u'2010-2014, OpenStack Foundation.' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. from glance.version import version_info as glance_version # The full version, including alpha/beta/rc tags. release = glance_version.version_string_with_vcs() # The short X.Y version. version = glance_version.canonical_version_string() # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. #language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: #today = '' # Else, today_fmt is used as the format for a strftime call. #today_fmt = '%B %d, %Y' # List of documents that shouldn't be included in the build. #unused_docs = [] # List of directories, relative to source directory, that shouldn't be searched # for source files. exclude_trees = ['api'] # The reST default role (for this markup: `text`) to use for all documents. #default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. #add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). #add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. show_authors = True # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' # A list of ignored prefixes for module index sorting. modindex_common_prefix = ['glance.'] # -- Options for man page output -------------------------------------------- # Grouping the document tree for man pages. # List of tuples 'sourcefile', 'target', u'title', u'Authors name', 'manual' man_pages = [ ('man/glanceapi', 'glance-api', u'Glance API Server', [u'OpenStack'], 1), ('man/glancecachecleaner', 'glance-cache-cleaner', u'Glance Cache Cleaner', [u'OpenStack'], 1), ('man/glancecachemanage', 'glance-cache-manage', u'Glance Cache Manager', [u'OpenStack'], 1), ('man/glancecacheprefetcher', 'glance-cache-prefetcher', u'Glance Cache Pre-fetcher', [u'OpenStack'], 1), ('man/glancecachepruner', 'glance-cache-pruner', u'Glance Cache Pruner', [u'OpenStack'], 1), ('man/glancecontrol', 'glance-control', u'Glance Daemon Control Helper ', [u'OpenStack'], 1), ('man/glancemanage', 'glance-manage', u'Glance Management Utility', [u'OpenStack'], 1), ('man/glanceregistry', 'glance-registry', u'Glance Registry Server', [u'OpenStack'], 1), ('man/glancereplicator', 'glance-replicator', u'Glance Replicator', [u'OpenStack'], 1), ('man/glancescrubber', 'glance-scrubber', u'Glance Scrubber Service', [u'OpenStack'], 1) ] # -- Options for HTML output ------------------------------------------------- # The theme to use for HTML and HTML Help pages. Major themes that come with # Sphinx are currently 'default' and 'sphinxdoc'. # html_theme_path = ["."] # html_theme = '_theme' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. #html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. #html_theme_path = ['_theme'] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". #html_title = None # A shorter title for the navigation bar. Default is the same as html_title. #html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. #html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. #html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. #html_last_updated_fmt = '%b %d, %Y' git_cmd = "git log --pretty=format:'%ad, commit %h' --date=local -n1" html_last_updated_fmt = os.popen(git_cmd).read() # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. #html_use_smartypants = True # Custom sidebar templates, maps document names to template names. #html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. #html_additional_pages = {} # If false, no module index is generated. html_use_modindex = False # If false, no index is generated. html_use_index = False # If true, the index is split into individual pages for each letter. #html_split_index = False # If true, links to the reST sources are added to the pages. #html_show_sourcelink = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. #html_use_opensearch = '' # If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml"). #html_file_suffix = '' # Output file base name for HTML help builder. htmlhelp_basename = 'glancedoc' # -- Options for LaTeX output ------------------------------------------------ # The paper size ('letter' or 'a4'). #latex_paper_size = 'letter' # The font size ('10pt', '11pt' or '12pt'). #latex_font_size = '10pt' # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, # documentclass [howto/manual]). latex_documents = [ ('index', 'Glance.tex', u'Glance Documentation', u'Glance Team', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of # the title page. #latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. #latex_use_parts = False # Additional stuff for the LaTeX preamble. #latex_preamble = '' # Documents to append as an appendix to all manuals. #latex_appendices = [] # If false, no module index is generated. #latex_use_modindex = True # Example configuration for intersphinx: refer to the Python standard library. intersphinx_mapping = {'python': ('http://docs.python.org/', None), 'nova': ('http://nova.openstack.org', None), 'swift': ('http://swift.openstack.org', None)} glance-2014.1/doc/source/configuring.rst0000664000175400017540000011653312323736230021313 0ustar jenkinsjenkins00000000000000.. Copyright 2011 OpenStack Foundation All Rights Reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Basic Configuration =================== Glance has a number of options that you can use to configure the Glance API server, the Glance Registry server, and the various storage backends that Glance can use to store images. Most configuration is done via configuration files, with the Glance API server and Glance Registry server using separate configuration files. When starting up a Glance server, you can specify the configuration file to use (see :doc:`the documentation on controller Glance servers `). If you do **not** specify a configuration file, Glance will look in the following directories for a configuration file, in order: * ``~/.glance`` * ``~/`` * ``/etc/glance`` * ``/etc`` The Glance API server configuration file should be named ``glance-api.conf``. Similarly, the Glance Registry server configuration file should be named ``glance-registry.conf``. If you installed Glance via your operating system's package management system, it is likely that you will have sample configuration files installed in ``/etc/glance``. In addition to this documentation page, you can check the ``etc/glance-api.conf`` and ``etc/glance-registry.conf`` sample configuration files distributed with Glance for example configuration files for each server application with detailed comments on what each options does. The PasteDeploy configuration (controlling the deployment of the WSGI 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:: [paste_deploy] config_file = /path/to/paste/config Common Configuration Options in Glance -------------------------------------- Glance has a few command-line options that are common to all Glance programs: * ``--verbose`` Optional. Default: ``False`` Can be specified on the command line and in configuration files. Turns on the INFO level in logging and prints more verbose command-line interface printouts. * ``--debug`` Optional. Default: ``False`` Can be specified on the command line and in configuration files. Turns on the DEBUG level in logging. * ``--config-file=PATH`` Optional. Default: See below for default search order. Specified on the command line only. Takes a path to a configuration file to use when running the program. If this CLI option is not specified, then we check to see if the first argument is a file. If it is, then we try to use that as the configuration file. If there is no file or there were no arguments, we search for a configuration file in the following order: * ``~/.glance`` * ``~/`` * ``/etc/glance`` * ``/etc`` The filename that is searched for depends on the server application name. So, if you are starting up the API server, ``glance-api.conf`` is searched for, otherwise ``glance-registry.conf``. * ``--config-dir=DIR`` Optional. Default: ``None`` Specified on the command line only. Takes a path to a configuration directory from which all \*.conf fragments are loaded. This provides an alternative to multiple --config-file options when it is inconvenient to explicitly enumerate all the config files, for example when an unknown number of config fragments are being generated by a deployment framework. If --config-dir is set, then --config-file is ignored. An example usage would be: $ glance-api --config-dir=/etc/glance/glance-api.d $ ls /etc/glance/glance-api.d 00-core.conf 01-s3.conf 02-swift.conf 03-ssl.conf ... etc. The numeric prefixes in the example above are only necessary if a specific parse ordering is required (i.e. if an individual config option set in an earlier fragment is overridden in a later fragment). Configuring Server Startup Options ---------------------------------- You can put the following options in the ``glance-api.conf`` and ``glance-registry.conf`` files, under the ``[DEFAULT]`` section. They enable startup and binding behaviour for the API and registry servers, respectively. * ``bind_host=ADDRESS`` The address of the host to bind to. Optional. Default: ``0.0.0.0`` * ``bind_port=PORT`` The port the server should bind to. Optional. Default: ``9191`` for the registry server, ``9292`` for the API server * ``backlog=REQUESTS`` Number of backlog requests to configure the socket with. Optional. Default: ``4096`` * ``tcp_keepidle=SECONDS`` Sets the value of TCP_KEEPIDLE in seconds for each server socket. Not supported on OS X. Optional. Default: ``600`` * ``workers=PROCESSES`` Number of Glance API worker processes to start. Each worker process will listen on the same port. Increasing this value may increase performance (especially if using SSL with compression enabled). Typically it is recommended to have one worker process per CPU. The value `0` will prevent any new processes from being created. Optional. Default: ``1`` * ``db_auto_create=False`` Whether to automatically create the database tables. Otherwise you can manually run `glance-manage db sync`. Optional. Default: ``False`` Configuring SSL Support ~~~~~~~~~~~~~~~~~~~~~~~~~ * ``cert_file=PATH`` Path to the certificate file the server should use when binding to an SSL-wrapped socket. Optional. Default: not enabled. * ``key_file=PATH`` Path to the private key file the server should use when binding to an SSL-wrapped socket. Optional. Default: not enabled. * ``ca_file=PATH`` Path to the CA certificate file the server should use to validate client certificates provided during an SSL handshake. This is ignored if ``cert_file`` and ''key_file`` are not set. Optional. Default: not enabled. Configuring Registry Access ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ There are a number of configuration options in Glance that control how the API server accesses the registry server. * ``registry_client_protocol=PROTOCOL`` If you run a secure Registry server, you need to set this value to ``https`` and also set ``registry_client_key_file`` and optionally ``registry_client_cert_file``. Optional. Default: http * ``registry_client_key_file=PATH`` The path to the key file to use in SSL connections to the registry server, if any. Alternately, you may set the ``GLANCE_CLIENT_KEY_FILE`` environ variable to a filepath of the key file Optional. Default: Not set. * ``registry_client_cert_file=PATH`` Optional. Default: Not set. The path to the cert file to use in SSL connections to the registry server, if any. Alternately, you may set the ``GLANCE_CLIENT_CERT_FILE`` environ variable to a filepath of the cert file * ``registry_client_ca_file=PATH`` Optional. Default: Not set. The path to a Certifying Authority's cert file to use in SSL connections to the registry server, if any. Alternately, you may set the ``GLANCE_CLIENT_CA_FILE`` environ variable to a filepath of the CA cert file * ``registry_client_insecure=False`` Optional. Default: False. When using SSL in connections to the registry server, do not require validation via a certifying authority. This is the registry's equivalent of specifying --insecure on the command line using glanceclient for the API * ``registry_client_timeout=SECONDS`` Optional. Default: ``600``. The period of time, in seconds, that the API server will wait for a registry request to complete. A value of '0' implies no timeout. * ``use_user_token=True`` Optional. Default: True Pass the user token through for API requests to the registry. If 'use_user_token' is not in effect then admin credentials can be specified (see below). If admin credentials are specified then they are used to generate a token; this token rather than the original user's token is used for requests to the registry. * ``admin_user=USER`` If 'use_user_token' is not in effect then admin credentials can be specified. Use this parameter to specify the username. Optional. Default: None * ``admin_password=PASSWORD`` If 'use_user_token' is not in effect then admin credentials can be specified. Use this parameter to specify the password. Optional. Default: None * ``admin_tenant_name=TENANTNAME`` If 'use_user_token' is not in effect then admin credentials can be specified. Use this parameter to specify the tenant name. Optional. Default: None * ``auth_url=URL`` If 'use_user_token' is not in effect then admin credentials can be specified. Use this parameter to specify the Keystone endpoint. Optional. Default: None * ``auth_strategy=STRATEGY`` If 'use_user_token' is not in effect then admin credentials can be specified. Use this parameter to specify the auth strategy. Optional. Default: keystone * ``auth_region=REGION`` If 'use_user_token' is not in effect then admin credentials can be specified. Use this parameter to specify the region. Optional. Default: None Configuring Logging in Glance ----------------------------- There are a number of configuration options in Glance that control how Glance servers log messages. * ``--log-config=PATH`` Optional. Default: ``None`` Specified on the command line only. Takes a path to a configuration file to use for configuring logging. Logging Options Available Only in Configuration Files ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ You will want to place the different logging options in the **[DEFAULT]** section in your application configuration file. As an example, you might do the following for the API server, in a configuration file called ``etc/glance-api.conf``:: [DEFAULT] log_file = /var/log/glance/api.log * ``log_file`` The filepath of the file to use for logging messages from Glance's servers. If missing, the default is to output messages to ``stdout``, so if you are running Glance servers in a daemon mode (using ``glance-control``) you should make sure that the ``log_file`` option is set appropriately. * ``log_dir`` The filepath of the directory to use for log files. If not specified (the default) the ``log_file`` is used as an absolute filepath. * ``log_date_format`` The format string for timestamps in the log output. Defaults to ``%Y-%m-%d %H:%M:%S``. See the `logging module `_ documentation for more information on setting this format string. * ``log_use_syslog`` Use syslog logging functionality. Defaults to False. Configuring Glance Storage Backends ----------------------------------- There are a number of configuration options in Glance that control how Glance stores disk images. These configuration options are specified in the ``glance-api.conf`` config file in the section ``[DEFAULT]``. * ``default_store=STORE`` Optional. Default: ``file`` Can only be specified in configuration files. Sets the storage backend to use by default when storing images in Glance. Available options for this option are (``file``, ``swift``, ``s3``, ``rbd``, ``sheepdog``, ``cinder`` or ``vsphere``). Configuring Glance Image Size Limit ----------------------------------- The following configuration option is specified in the ``glance-api.conf`` config file in the section ``[DEFAULT]``. * ``image_size_cap=SIZE`` Optional. Default: ``1099511627776`` (1 TB) Maximum image size, in bytes, which can be uploaded through the Glance API server. **IMPORTANT NOTE**: this value should only be increased after careful consideration and must be set to a value under 8 EB (9223372036854775808). Configuring Glance User Storage Quota ------------------------------------- The following configuration option is specified in the ``glance-api.conf`` config file in the section ``[DEFAULT]``. * ``user_storage_quota`` Optional. Default: 0 (Unlimited). This value specifies the maximum amount of bytes that each user can use across all storage systems. Configuring the Filesystem Storage Backend ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * ``filesystem_store_datadir=PATH`` Optional. Default: ``/var/lib/glance/images/`` Can only be specified in configuration files. `This option is specific to the filesystem storage backend.` Sets the path where the filesystem storage backend write disk images. Note that the filesystem storage backend will attempt to create this directory if it does not exist. Ensure that the user that ``glance-api`` runs under has write permissions to this directory. Configuring the Filesystem Storage Backend with multiple stores ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * ``filesystem_store_datadirs=PATH:PRIORITY`` Optional. Default: ``/var/lib/glance/images/:1`` Example:: filesystem_store_datadirs = /var/glance/store filesystem_store_datadirs = /var/glance/store1:100 filesystem_store_datadirs = /var/glance/store2:200 This option can only be specified in configuration file and is specific to the filesystem storage backend only. filesystem_store_datadirs option allows administrators to configure multiple store directories to save glance image in filesystem storage backend. Each directory can be coupled with its priority. **NOTE**: * This option can be specified multiple times to specify multiple stores. * Either filesystem_store_datadir or filesystem_store_datadirs option must be specified in glance-api.conf * Store with priority 200 has precedence over store with priority 100. * If no priority is specified, default priority '0' is associated with it. * If two filesystem stores have same priority store with maximum free space will be chosen to store the image. * If same store is specified multiple times then BadStoreConfiguration exception will be raised. Configuring the Swift Storage Backend ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * ``swift_store_auth_address=URL`` Required when using the Swift storage backend. Can only be specified in configuration files. `This option is specific to the Swift storage backend.` Sets the authentication URL supplied to Swift when making calls to its storage system. For more information about the Swift authentication system, please see the `Swift auth `_ documentation and the `overview of Swift authentication `_. **IMPORTANT NOTE**: Swift authentication addresses use HTTPS by default. This means that if you are running Swift with authentication over HTTP, you need to set your ``swift_store_auth_address`` to the full URL, including the ``http://``. * ``swift_store_user=USER`` Required when using the Swift storage backend. Can only be specified in configuration files. `This option is specific to the Swift storage backend.` Sets the user to authenticate against the ``swift_store_auth_address`` with. * ``swift_store_key=KEY`` Required when using the Swift storage backend. Can only be specified in configuration files. `This option is specific to the Swift storage backend.` Sets the authentication key to authenticate against the ``swift_store_auth_address`` with for the user ``swift_store_user``. * ``swift_store_container=CONTAINER`` Optional. Default: ``glance`` Can only be specified in configuration files. `This option is specific to the Swift storage backend.` Sets the name of the container to use for Glance images in Swift. * ``swift_store_create_container_on_put`` Optional. Default: ``False`` Can only be specified in configuration files. `This option is specific to the Swift storage backend.` If true, Glance will attempt to create the container ``swift_store_container`` if it does not exist. * ``swift_store_large_object_size=SIZE_IN_MB`` Optional. Default: ``5120`` Can only be specified in configuration files. `This option is specific to the Swift storage backend.` What size, in MB, should Glance start chunking image files and do a large object manifest in Swift? By default, this is the maximum object size in Swift, which is 5GB * ``swift_store_large_object_chunk_size=SIZE_IN_MB`` Optional. Default: ``200`` Can only be specified in configuration files. `This option is specific to the Swift storage backend.` When doing a large object manifest, what size, in MB, should Glance write chunks to Swift? The default is 200MB. * ``swift_store_multi_tenant=False`` Optional. Default: ``False`` Can only be specified in configuration files. `This option is specific to the Swift storage backend.` If set to True enables multi-tenant storage mode which causes Glance images to be stored in tenant specific Swift accounts. When set to False Glance stores all images in a single Swift account. * ``swift_store_admin_tenants`` Can only be specified in configuration files. `This option is specific to the Swift storage backend.` Optional. Default: Not set. A list of swift ACL strings that will be applied as both read and write ACLs to the containers created by Glance in multi-tenant mode. This grants the specified tenants/users read and write access to all newly created image objects. The standard swift ACL string formats are allowed, including: : : \*: Multiple ACLs can be combined using a comma separated list, for example: swift_store_admin_tenants = service:glance,*:admin * ``swift_store_auth_version`` Can only be specified in configuration files. `This option is specific to the Swift storage backend.` Optional. Default: ``2`` A string indicating which version of Swift OpenStack authentication to use. See the project `python-swiftclient `_ for more details. * ``swift_store_service_type`` Can only be specified in configuration files. `This option is specific to the Swift storage backend.` Optional. Default: ``object-store`` A string giving the service type of the swift service to use. This setting is only used if swift_store_auth_version is ``2``. * ``swift_store_region`` Can only be specified in configuration files. `This option is specific to the Swift storage backend.` Optional. Default: Not set. A string giving the region of the swift service endpoint to use. This setting is only used if swift_store_auth_version is ``2``. This setting is especially useful for disambiguation if multiple swift services might appear in a service catalog during authentication. * ``swift_store_endpoint_type`` Can only be specified in configuration files. `This option is specific to the Swift storage backend.` Optional. Default: ``publicURL`` A string giving the endpoint type of the swift service endpoint to use. This setting is only used if swift_store_auth_version is ``2``. * ``swift_store_ssl_compression`` Can only be specified in configuration files. `This option is specific to the Swift storage backend.` Optional. Default: True. If set to False, disables SSL layer compression of https swift requests. Setting to 'False' may improve performance for images which are already in a compressed format, eg qcow2. If set to True then compression will be enabled (provided it is supported by the swift proxy). * ``swift_store_retry_get_count`` The number of times a Swift download will be retried before the request fails. Can only be specified in configuration files. `This option is specific to the Swift storage backend.` Optional. Default: ``0`` Configuring the S3 Storage Backend ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * ``s3_store_host=URL`` Required when using the S3 storage backend. Can only be specified in configuration files. `This option is specific to the S3 storage backend.` Default: s3.amazonaws.com Sets the main service URL supplied to S3 when making calls to its storage system. For more information about the S3 authentication system, please see the `S3 documentation `_ * ``s3_store_access_key=ACCESS_KEY`` Required when using the S3 storage backend. Can only be specified in configuration files. `This option is specific to the S3 storage backend.` Sets the access key to authenticate against the ``s3_store_host`` with. You should set this to your 20-character Amazon AWS access key. * ``s3_store_secret_key=SECRET_KEY`` Required when using the S3 storage backend. Can only be specified in configuration files. `This option is specific to the S3 storage backend.` Sets the secret key to authenticate against the ``s3_store_host`` with for the access key ``s3_store_access_key``. You should set this to your 40-character Amazon AWS secret key. * ``s3_store_bucket=BUCKET`` Required when using the S3 storage backend. Can only be specified in configuration files. `This option is specific to the S3 storage backend.` Sets the name of the bucket to use for Glance images in S3. Note that the namespace for S3 buckets is **global**, therefore you must use a name for the bucket that is unique. It is recommended that you use a combination of your AWS access key, **lowercased** with "glance". For instance if your Amazon AWS access key is: ``ABCDEFGHIJKLMNOPQRST`` then make your bucket value be: ``abcdefghijklmnopqrstglance`` * ``s3_store_create_bucket_on_put`` Optional. Default: ``False`` Can only be specified in configuration files. `This option is specific to the S3 storage backend.` If true, Glance will attempt to create the bucket ``s3_store_bucket`` if it does not exist. * ``s3_store_object_buffer_dir=PATH`` Optional. Default: ``the platform's default temporary directory`` Can only be specified in configuration files. `This option is specific to the S3 storage backend.` When sending images to S3, what directory should be used to buffer the chunks? By default the platform's temporary directory will be used. Configuring the RBD Storage Backend ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ **Note**: the RBD storage backend requires the python bindings for librados and librbd. These are in the python-ceph package on Debian-based distributions. * ``rbd_store_pool=POOL`` Optional. Default: ``rbd`` Can only be specified in configuration files. `This option is specific to the RBD storage backend.` Sets the RADOS pool in which images are stored. * ``rbd_store_chunk_size=CHUNK_SIZE_MB`` Optional. Default: ``4`` Can only be specified in configuration files. `This option is specific to the RBD storage backend.` Images will be chunked into objects of this size (in megabytes). For best performance, this should be a power of two. * ``rbd_store_ceph_conf=PATH`` Optional. Default: ``/etc/ceph/ceph.conf``, ``~/.ceph/config``, and ``./ceph.conf`` Can only be specified in configuration files. `This option is specific to the RBD storage backend.` Sets the Ceph configuration file to use. * ``rbd_store_user=NAME`` Optional. Default: ``admin`` Can only be specified in configuration files. `This option is specific to the RBD storage backend.` Sets the RADOS user to authenticate as. This is only needed when `RADOS authentication `_ is `enabled. `_ A keyring must be set for this user in the Ceph configuration file, e.g. with a user ``glance``:: [client.glance] keyring=/etc/glance/rbd.keyring To set up a user named ``glance`` with minimal permissions, using a pool called ``images``, run:: rados mkpool images ceph-authtool --create-keyring /etc/glance/rbd.keyring ceph-authtool --gen-key --name client.glance --cap mon 'allow r' --cap osd 'allow rwx pool=images' /etc/glance/rbd.keyring ceph auth add client.glance -i /etc/glance/rbd.keyring Configuring the Sheepdog Storage Backend ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * ``sheepdog_store_address=ADDR`` Optional. Default: ``localhost`` Can only be specified in configuration files. `This option is specific to the Sheepdog storage backend.` Sets the IP address of the sheep daemon * ``sheepdog_store_port=PORT`` Optional. Default: ``7000`` Can only be specified in configuration files. `This option is specific to the Sheepdog storage backend.` Sets the IP port of the sheep daemon * ``sheepdog_store_chunk_size=SIZE_IN_MB`` Optional. Default: ``64`` Can only be specified in configuration files. `This option is specific to the Sheepdog storage backend.` Images will be chunked into objects of this size (in megabytes). For best performance, this should be a power of two. Configuring the Cinder Storage Backend ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ **Note**: Currently Cinder store is a partial implementation. After Cinder expose 'brick' library, and 'Readonly-volume-attaching', 'volume-multiple-attaching' enhancement ready, the store will support 'Upload' and 'Download' interface finally. * ``cinder_catalog_info=::`` Optional. Default: ``volume:cinder:publicURL`` Can only be specified in configuration files. `This option is specific to the Cinder storage backend.` Sets the info to match when looking for cinder in the service catalog. Format is : separated values of the form: :: * ``cinder_endpoint_template=http://ADDR:PORT/VERSION/%(project_id)s`` Optional. Default: ``None`` Can only be specified in configuration files. Override service catalog lookup with template for cinder endpoint. e.g. http://localhost:8776/v1/%(project_id)s * ``os_region_name=REGION_NAME`` Optional. Default: ``None`` Can only be specified in configuration files. Region name of this node. * ``cinder_ca_certificates_file=CA_FILE_PATH`` Optional. Default: ``None`` Can only be specified in configuration files. Location of ca certicates file to use for cinder client requests. * ``cinder_http_retries=TIMES`` Optional. Default: ``3`` Can only be specified in configuration files. Number of cinderclient retries on failed http calls. * ``cinder_api_insecure=ON_OFF`` Optional. Default: ``False`` Can only be specified in configuration files. Allow to perform insecure SSL requests to cinder. Configuring the Image Cache --------------------------- Glance API servers can be configured to have a local image cache. Caching of image files is transparent and happens using a piece of middleware that can optionally be placed in the server application pipeline. This pipeline is configured in the PasteDeploy configuration file, -paste.ini. You should not generally have to edit this file directly, as it ships with ready-made pipelines for all common deployment flavors. Enabling the Image Cache Middleware ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ To enable the image cache middleware, the cache middleware must occur in the application pipeline **after** the appropriate context middleware. The cache middleware should be in your ``glance-api-paste.ini`` in a section titled ``[filter:cache]``. It should look like this:: [filter:cache] paste.filter_factory = glance.api.middleware.cache:CacheFilter.factory A ready-made application pipeline including this filter is defined in the ``glance-api-paste.ini`` file, looking like so:: [pipeline:glance-api-caching] pipeline = versionnegotiation context cache apiv1app To enable the above application pipeline, in your main ``glance-api.conf`` configuration file, select the appropriate deployment flavor like so:: [paste_deploy] flavor = caching Enabling the Image Cache Management Middleware ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ There is an optional ``cachemanage`` middleware that allows you to directly interact with cache images. Use this flavor in place of the ``cache`` flavor in your api config file. [paste_deploy] flavor = cachemanage Configuration Options Affecting the Image Cache ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. note:: These configuration options must be set in both the glance-cache and glance-api configuration files. One main configuration file option affects the image cache. * ``image_cache_dir=PATH`` Required when image cache middleware is enabled. Default: ``/var/lib/glance/image-cache`` This is the base directory the image cache can write files to. Make sure the directory is writeable by the user running the ``glance-api`` server * ``image_cache_driver=DRIVER`` Optional. Choice of ``sqlite`` or ``xattr`` Default: ``sqlite`` The default ``sqlite`` cache driver has no special dependencies, other than the ``python-sqlite3`` library, which is installed on virtually all operating systems with modern versions of Python. It stores information about the cached files in a SQLite database. The ``xattr`` cache driver required the ``python-xattr>=0.6.0`` library and requires that the filesystem containing ``image_cache_dir`` have access times tracked for all files (in other words, the noatime option CANNOT be set for that filesystem). In addition, ``user_xattr`` must be set on the filesystem's description line in fstab. Because of these requirements, the ``xattr`` cache driver is not available on Windows. * ``image_cache_sqlite_db=DB_FILE`` Optional. Default: ``cache.db`` When using the ``sqlite`` cache driver, you can set the name of the database that will be used to store the cached images information. The database is always contained in the ``image_cache_dir``. * ``image_cache_max_size=SIZE`` Optional. Default: ``10737418240`` (10 GB) Size, in bytes, that the image cache should be constrained to. Images files are cached automatically in the local image cache, even if the writing of that image file would put the total cache size over this size. The ``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 :doc:`Controlling the Growth of the Image Cache ` Configuring the Glance Registry ------------------------------- 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]``. **IMPORTANT NOTE**: The glance-registry service is only used in conjunction with the glance-api service when clients are using the v1 REST API. See `Configuring Glance APIs`_ for more info. * ``sql_connection=CONNECTION_STRING`` (``--sql-connection`` when specified on command line) Optional. Default: ``None`` Can be specified in configuration files. Can also be specified on the command-line for the ``glance-manage`` program. Sets the SQLAlchemy connection string to use when connecting to the registry database. Please see the documentation for `SQLAlchemy connection strings `_ online. You must urlencode any special characters in CONNECTION_STRING. * ``sql_timeout=SECONDS`` on command line) Optional. Default: ``3600`` Can only be specified in configuration files. Sets the number of seconds after which SQLAlchemy should reconnect to the datastore if no activity has been made on the connection. * ``enable_v1_registry=`` Optional. Default: ``True`` * ``enable_v2_registry=`` Optional. Default: ``True`` Defines which version(s) of the Registry API will be enabled. If the Glance API server parameter ``enable_v1_api`` has been set to ``True`` the ``enable_v1_registry`` has to be ``True`` as well. If the Glance API server parameter ``enable_v2_api`` has been set to ``True`` and the parameter ``data_api`` has been set to ``glance.db.registry.api`` the ``enable_v2_registry`` has to be set to ``True`` Configuring Notifications ------------------------- Glance can optionally generate notifications to be logged or sent to a RabbitMQ queue. The configuration options are specified in the ``glance-api.conf`` config file in the section ``[DEFAULT]``. * ``notifier_strategy`` Optional. Default: ``noop`` Sets the strategy used for notifications. Options are ``logging``, ``rabbit``, ``qpid`` and ``noop``. For more information :doc:`Glance notifications ` * ``rabbit_host`` Optional. Default: ``localhost`` Host to connect to when using ``rabbit`` strategy. * ``rabbit_port`` Optional. Default: ``5672`` Port to connect to when using ``rabbit`` strategy. * ``rabbit_use_ssl`` Optional. Default: ``false`` Boolean to use SSL for connecting when using ``rabbit`` strategy. * ``rabbit_userid`` Optional. Default: ``guest`` Userid to use for connection when using ``rabbit`` strategy. * ``rabbit_password`` Optional. Default: ``guest`` Password to use for connection when using ``rabbit`` strategy. * ``rabbit_virtual_host`` Optional. Default: ``/`` Virtual host to use for connection when using ``rabbit`` strategy. * ``rabbit_notification_exchange`` Optional. Default: ``glance`` Exchange name to use for connection when using ``rabbit`` strategy. * ``rabbit_notification_topic`` Optional. Default: ``notifications`` Topic to use for connection when using ``rabbit`` strategy. * ``rabbit_max_retries`` Optional. Default: ``0`` Number of retries on communication failures when using ``rabbit`` strategy. A value of 0 means to retry forever. * ``rabbit_retry_backoff`` Optional. Default: ``2`` Number of seconds to wait before reconnecting on failures when using ``rabbit`` strategy. * ``rabbit_retry_max_backoff`` Optional. Default: ``30`` Maximum seconds to wait before reconnecting on failures when using ``rabbit`` strategy. * ``rabbit_durable_queues`` Optional. Default: ``False`` Controls durability of exchange and queue when using ``rabbit`` strategy. * ``qpid_notification_exchange`` Optional. Default: ``glance`` Message exchange to use when using the ``qpid`` notification strategy. * ``qpid_notification_topic`` Optional. Default: ``glanice_notifications`` This is the topic prefix for notifications when using the ``qpid`` notification strategy. When a notification is sent at the ``info`` priority, the topic will be ``notifications.info``. The same idea applies for the ``error`` and ``warn`` notification priorities. To receive all notifications, you would set up a receiver with a topic of ``notifications.*``. * ``qpid_hostname`` Optional. Default: ``localhost`` This is the hostname or IP address of the Qpid broker that will be used when Glance has been configured to use the ``qpid`` notification strategy. * ``qpid_port`` Optional. Default: ``5672`` This is the port number to connect to on the Qpid broker, ``qpid_hostname``, when using the ``qpid`` notification strategy. * ``qpid_username`` Optional. Default: None This is the username that Glance will use to authenticate with the Qpid broker if using the ``qpid`` notification strategy. * ``qpid_password`` Optional. Default: None This is the username that Glance will use to authenticate with the Qpid broker if using the ``qpid`` notification strategy. * ``qpid_sasl_mechanisms`` Optional. Default: None This is a space separated list of SASL mechanisms to use for authentication with the Qpid broker if using the ``qpid`` notification strategy. * ``qpid_reconnect_timeout`` Optional. Default: None This option specifies a timeout in seconds for automatic reconnect attempts to the Qpid broker if the ``qpid`` notification strategy is used. In general, it is safe to leave all of the reconnect timing options not set. In that case, the Qpid client's default behavior will be used, which is to attempt to reconnect to the broker at exponential back-off intervals (in 1 second, then 2 seconds, then 4, 8, 16, etc). * ``qpid_reconnect_limit`` Optional. Default: None This option specifies a maximum number of reconnect attempts to the Qpid broker if the ``qpid`` notification strategy is being used. Normally the Qpid client will continue attempting to reconnect until successful. * ``qpid_reconnect_interval_min`` Optional. Default: None This option specifies the minimum number of seconds between reconnection attempts if the ``qpid`` notification strategy is being used. * ``qpid_reconnect_interval_max`` Optional. Default: None This option specifies the maximum number of seconds between reconnection attempts if the ``qpid`` notification strategy is being used. * ``qpid_reconnect_interval`` This option specifies the exact number of seconds between reconnection attempts if the ``qpid`` notification strategy is being used. Setting this option is equivalent to setting ``qpid_reconnect_interval_max`` and ``qpid_reconnect_interval_min`` to the same value. * ``qpid_heartbeat`` Optional. Default: ``5`` This option is used to specify the number of seconds between heartbeat messages exchanged between the Qpid client and Qpid broker if the ``qpid`` notification strategy is being used. Heartbeats are used to more quickly detect that a connection has been lost. * ``qpid_protocol`` Optional. Default: ``tcp`` This option is used to specify the transport protocol to use if using the ``qpid`` notification strategy. To enable SSL, set this option to ``ssl``. * ``qpid_tcp_nodelay`` Optional. Default: ``True`` This option can be used to disable the TCP NODELAY option. It effectively disables the Nagle algorithm for the connection to the Qpid broker. This option only applies if the ``qpid`` notification strategy is used. Configuring Access Policies --------------------------- Access rules may be configured using a :doc:`Policy Configuration file `. Two configuration options tell the Glance API server about the policies to use. * ``policy_file=PATH`` Optional. Default: Looks for a file called ``policy.json`` or ``glance.policy.json`` in standard configuration directories. Policy file to load when starting the API server * ``policy_default_rule=RULE`` Optional. Default: "default" Name of the rule in the policy configuration file to use as the default rule Configuring Glance Property Protections --------------------------------------- Access to image meta properties may be configured using a :doc:`Property Protections Configuration file `. The location for this file can be specified in the ``glance-api.conf`` config file in the section ``[DEFAULT]``. **If an incorrect value is specified, glance api service will not start.** * ``property_protection_file=PATH`` Optional. Default: not enabled. If property_protection_file is set, the file may use either roles or policies to specify property protections. * ``property_protection_rule_format=`` Optional. Default: ``roles``. Configuring Glance APIs ----------------------- The glance-api service implents versions 1 and 2 of the OpenStack Images API. Disable either version of the Images API using the following options: * ``enable_v1_api=`` Optional. Default: ``True`` * ``enable_v2_api=`` Optional. Default: ``True`` **IMPORTANT NOTE**: The v1 API is implemented on top of the glance-registry service while the v2 API is not. This means that in order to use the v2 API, you must copy the necessary sql configuration from your glance-registry service to your glance-api configuration file. Configuring Glance Tasks ------------------------ Glance Tasks are implemented only for version 2 of the OpenStack Images API. ``Please be aware that Glance tasks are currently a work in progress feature.`` Although, the API is available, the execution part of it is being worked on. The config value ``task_time_to_live`` is used to determine how long a task would be visible to the user after transitioning to either the ``success`` or the ``failure`` state. * ``task_time_to_live=`` Optional. Default: ``48`` glance-2014.1/doc/source/images_src/0000775000175400017540000000000012323736427020362 5ustar jenkinsjenkins00000000000000glance-2014.1/doc/source/images_src/image_status_transition.dot0000664000175400017540000000300612323736226026025 0ustar jenkinsjenkins00000000000000/* # All Rights Reserved. # Copyright 2013 IBM Corp. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. */ /* This file can be compiled by graphviz with issuing the following command: dot -Tpng -oimage_status_transition.png image_status_transition.dot See http://www.graphviz.org to get more info. */ digraph { node [shape="doublecircle" color="#006699" style="filled" fillcolor="#33CCFF" fixedsize="True" width="1.5" height="1.5"]; "" -> "queued" [label="create image"]; "queued" -> "active" [label="add location*"]; "queued" -> "saving" [label="upload"]; "queued" -> "deleted" [label="delete"]; "saving" -> "active" [label="upload succeed"]; "saving" -> "killed" [label="upload fail"]; "saving" -> "deleted" [label="delete"]; "active" -> "queued" [label="remove location*"]; "active" -> "pending_delete" [label="delayed delete"]; "active" -> "deleted" [label="delete"]; "killed" -> "deleted" [label="delete"]; "pending_delete" -> "deleted" [label="after scrub time"]; } glance-2014.1/doc/source/property-protections.rst0000664000175400017540000001145412323736226023235 0ustar jenkinsjenkins00000000000000.. Copyright 2013 OpenStack Foundation All Rights Reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Property Protections ==================== There are two types of image properties in Glance: * Core Properties, as specified by the image schema. * Meta Properties, which are arbitrary key/value pairs that can be added to an image. Access to meta properties through Glance's public API calls may be restricted to certain sets of users, using a property protections configuration file. This document explains exactly how property protections are configured and what they apply to. Constructing a Property Protections Configuration File ------------------------------------------------------ A property protections configuration file follows the format of the Glance API configuration file, which consists of sections, led by a ``[section]`` header and followed by ``name = value`` entries. Each section header is a regular expression matching a set of properties to be protected. .. note:: Section headers must compile to a valid regular expression, otherwise glance api service will not start. Regular expressions will be handled by python's re module which is PERL like. Each section describes four key-value pairs, where the key is one of ``create/read/update/delete``, and the value is a comma separated list of user roles that are permitted to perform that operation in the Glance API. **If any of the keys are not specified, then the glance api service will not start successfully.** In the list of user roles, ``@`` means all roles and ``!`` means no role. **If both @ and ! are specified for the same rule then the glance api service will not start** .. note:: Only one policy rule is allowed per property operation. **If multiple are specified, then the glance api service will not start.** The path to the file should be specified in the ``[DEFAULT]`` section of ``glance-api.conf`` as follows. :: property_protection_file=/path/to/file If this config value is not specified, property protections are not enforced. **If the path is invalid, glance api service will not start successfully.** The file may use either roles or policies to describe the property protections. The config value should be specified in the ``[DEFAULT]`` section of ``glance-api.conf`` as follows. :: property_protection_rule_format= The default value for ``property_protection_rule_format`` is ``roles``. Property protections are applied in the order specified in the configuration file. This means that if for example you specify a section with ``[.*]`` at the top of the file, all proceeding sections will be ignored. If a property does not match any of the given rules, all operations will be disabled for all roles. If an operation is misspelled or omitted, that operation will be disabled for all roles. Disallowing ``read`` operations will also disallow ``update/delete`` operations. A successful HTTP request will return status ``200 OK``. If the user is not permitted to perform the requested action, ``403 Forbidden`` will be returned. V1 API X-glance-registry-Purge-props ------------------------------------ Property protections will still be honoured if ``X-glance-registry-Purge-props`` is set to ``True``. That is, if you request to modify properties with this header set to ``True``, you will not be able to delete or update properties for which you do not have the relevant permissions. Properties which are not included in the request and for which you do have delete permissions will still be removed. Examples -------- **Example 1**. Limit all property interactions to admin only. :: [.*] create = admin read = admin update = admin delete = admin **Example 2**. Allow both admins and users with the billing role to read and modify properties prefixed with ``x_billing_code_``. Allow admins to read and modify any properties. :: [^x_billing_code_.*] create = admin,billing read = admin, billing update = admin,billing delete = admin,billing [.*] create = admin read = admin update = admin delete = admin **Example 3**. Limit all property interactions to admin only using policy rule context_is_admin defined in policy.json. :: [.*] create = context_is_admin read = context_is_admin update = context_is_admin delete = context_is_admin glance-2014.1/doc/source/index.rst0000664000175400017540000000432012323736226020103 0ustar jenkinsjenkins00000000000000.. Copyright 2010 OpenStack Foundation All Rights Reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Welcome to Glance's documentation! ================================== The Glance project provides services for discovering, registering, and retrieving virtual machine images. Glance has a RESTful API that allows querying of VM image metadata as well as retrieval of the actual image. VM images made available through Glance can be stored in a variety of locations from simple filesystems to object-storage systems like the OpenStack Swift project. Glance, as with all OpenStack projects, is written with the following design guidelines in mind: * **Component based architecture**: Quickly add new behaviors * **Highly available**: Scale to very serious workloads * **Fault tolerant**: Isolated processes avoid cascading failures * **Recoverable**: Failures should be easy to diagnose, debug, and rectify * **Open standards**: Be a reference implementation for a community-driven api This documentation is generated by the Sphinx toolkit and lives in the source tree. Additional documentation on Glance and other components of OpenStack can be found on the `OpenStack wiki`_. .. _`OpenStack wiki`: http://wiki.openstack.org Concepts ======== .. toctree:: :maxdepth: 1 identifiers statuses formats common-image-properties Installing/Configuring Glance ============================= .. toctree:: :maxdepth: 1 installing configuring authentication policies Operating Glance ================ .. toctree:: :maxdepth: 1 controllingservers db cache notifications Using Glance ============ .. toctree:: :maxdepth: 1 glanceapi glanceclient glance-2014.1/doc/source/images/0000775000175400017540000000000012323736427017513 5ustar jenkinsjenkins00000000000000glance-2014.1/doc/source/images/image_status_transition.png0000664000175400017540000040076012323736226025164 0ustar jenkinsjenkins00000000000000‰PNG  IHDR¬•@rŒbKGDÿÿÿ ½§“ IDATxœìÝw\wúðÙ¾lƒ]XÚÒ‹4±¡€Ø°Ç£IL×ÔKL/—rwI~—K®äLr©w©¦˜˜ÄM¢±Ä®"½³ô]Øe{™ßk†QÙe?ïWþÈ<;3< 8Ÿ™ùÎw$Iày˜t7ô@ðPŠMw#Îh±©õ&dzÍh±,VÇG|Ë‹ÃæsXRO*àI…\/~)ÀSàß;S:õæ"¥ªH©ªhÕT¶]üOo¶}^v´\-—DÉűþÞIÁÒd…L*à\ÏtaàépkF‹íDM[nUsNEËéúŽzu7A"'Öß;Z.‰ñ—DË%r1_*àÉ„<©€'àö| f›JoTëÌj½©­Ûàˆ­šòÖ.­ÑB„ÂG8)Ô7#:`Ftà´y¿;p;à–Š”ªÝEõ»ÎÕçV5›­v™ç8<'+dÉ Y”Ÿ„Á†¯B’DM‡ö\£ê\£êDM[Nes{·‘Ãb¦Gù/¶d|èÄßaø24A·a'ÉcU-?Tÿtºº¶£[&äÍWÌWÌŠ L”ËQp$I”4wæT6ï¿Ð¸ÿBc‡Î"®šysJä̘@æ(t0¬À \hêü,»dóÉÊÆN]| Ïꔨ¥ãæEÈYLÚŽ»v’,¨mßUT·¥ ê¼Rä-Xõ‡Yñãƒetµp¥Àu™¬¶Í'+?Í*É®h•ŠÖN½%%zBÈå²V»½¬¥«²MSÝ®­éÐ*;õ-Zc›Î¤Ò»–K×ñ92!ÏWÈ ñƒ}‘¾’H?q”\àÃa]þ1ÚóJõ••×thÓ£üÿ03áöÔh9Zb'Éusž_4I.æ_]# !\…ÆhþϾsoï?Çç°žY˜üЬDA?‡p›´´ @AØIòã£þüS¾LÈûø®Y Bú¬ÐÔ¥ÿ×îÓg]`°9Ò„xÿÄñ¡ ³· mÅÅêâb›Å|ÿŒ¸—L‘ û¬s¨Tùà7G[4†¿ß0íÑÌ$§:@€ÑVÙ¦¹sÃÁSõí¾nòŸ®›Äç°œ?mï6þs÷éÿ.fò¹þ'ûÆÅ1ÙnöÀ½Ýfë(+k;uÊj4¬›ðâ’É/ç,6ûöŸýëö‚ !²oïŸã/¡«Uðp0ª¶Ÿ©½ã ŸûÍýs§G8d¶Úß?Tô·…f‚)Ÿ0I>>‘Ér³Ã¿3»ÍÖ^|¡íô)–Ýöò²IOÍOæ±{Å“µmwn8ئ5~²fÖÍS¢èê<BŒ«ÝþÜÇß9pqïÝ:CÌï5znÏùú‡¿Ë­WwË“’'ObqÇÈÓtv‹¥ùô™¶¢³AÁÿnËX>¡×@Éúô–ÜO³JÉL|{u—`T!ÀhhÕnùdÿÉÚ¶O×̾}ZŒóGj½éé-ǾÊ-ó‹Ž JMçŠEt59rÌ:]s~~[yùi1ïÞ’á'ê5wÐÖÂê{¿:œ¬myp!f€Ñ„#îdmÛª÷ ¸ì­ëöy¿ÎÎsu÷n<ª³3‚gÌòãÎi”ÙY<»õ³»f­šáüQIsçííÔ›·®[Øç. ÀÈA€‘µíTõšÏÍ Þtÿ¸m&rŒ(„~V»ýž/o-¬þáÁ×Ow®?ö}îÇGŠý““CÒÓ  O’¤òĉ–3§×NûäÎYÎìî¿·c| ?Ün„aóÖ¾³ÿ;rþ‹{æ8'€sª”þ¬bñ£W¬@G(Œ¾~…N I}ý—ÓõT}Ftà×÷Îû4«äŸ»OÑØŒU0<¶T=¿õø»·f8OXÞÚ5ÿ]¡(rñ’13ðarØ Ù%Ò¹oï,Rª¨úªÉÝ5óåí'¾Î+§±=“`ì¿Ðx熃Ï/žøhfU¬íèžóŸ&/qä’e,Àå19œÈ%ב>²¹oïªhÕPõûgÄÿuyʽ_Þ~¦–Æö`ìÁ˜¸Vuªî©ÿÜ–¸íá…Ìßo\7kôië·« nôÒåHWÄn±TîÚ%²èòž_*½x…$‰Û>Û¿¯¸ñÄ_V9¸pMt&kÆúŸ9,fös7ð9_•«5Zf¼±£Zo‹^~=›Ï|p)›É\¹sGÇ~üù|#”Éj›ýÆŽ.ƒùøŸW:?LpÕp;®ÉãßçÔ©º¿{`>•LVÛÒöTt£–.C¸:,7jé²Fƒmþ;»ôf«£Èc³6?8¿½Ûøð¦lzÛ€1!®ÞƼ²/•~}ï¼XoªøØ÷¹y5m r:%ð°`óùá kê|pSUŒð÷‡y›OV~’uÆÞ`Ì@€«TÚÒùÈ·ÙÏ/š´|BÏ+€?ɺ°!ûBxæ\\>ȶ0^2Yøüù߯x÷@U\˜òò²)OnÎ=Û d[€¡À˜¸›}ú¿f1˜Ùϯ &·?RÖ4ÿ“¦¥L¡·½±¤åÌÙÆüã»¿ŽšÑj·ÏysG—Á|ò/7Rwa®®ÀÕxçÀ¹óJõçwÏ¡€Zoº}Ã!‰B4e2½½1&H#Â×|q¤MktTØLæW÷Ì­íè^ÿÛz{w‡W¬¤¹óå_N¾ºbjR°”*Þóå‘.;>w>ém‡ƒÏœg`qnßpºlã/yýÆÔ×vžiètc€Á À•!Ibݦ¬ñ éÓ ’©â†œ’_ÏՆΙ‡)F“Ã;ïp©òƒÃ=ƒž“˜éÿÐ7YvÜÑ€«…WfóÉÊìŠæÿÝ1“ͼøÃ£ìÔ?½%Ož4^Hooc˜P.÷Ÿ8ñ…m'j:´Ž “Áøàöµía:a¸JpºM–gÌ[7;15¢çuÀ÷n9ü ÛŽwêÍ´¶î !®À¿÷œ1Zl¯Ý0•ªüXXµ÷|}Ðô  ÃÔGƒÁ š>#»BùÍñžSÿ¿.Oa2ßUHccà¾`¨”ú·œýó’IRÏQÑ™¬}Ì76V¢|[¢ @¿¸ø§ÌÓ/žú‹ùœ——MùïáóÔm€¡C€¡úÇîB?ÿñ¹ã©Ê?wŸR›,!éé4våiii:ù·=§þÎŽ“‰^ýàŠ!À”¶t~|ôÂ+˧rÙfj:´oî;09…íåEoo…Åãù§L{ïPQiK§£Âf2_]1uc^Yq“šÞÞÀí Àü{Ï™_ñi1Tåo¿rE"yb]y&¿ø8/oŸ¿:] ¸yJÔ¸ï×vâb\„¸¼zu÷7ÇËÿ²d25?à…¦Îyeþ)Ó,ü6ƒé?mÚ'+N×_œ)ˆÅd¼´tÊ–‚ªÊ6 ½½€{Á¿àpyoï?(¬I¥*ÿ·ã¤P&•FEÑØ•'ó Ëå/m?IUná+~sïY»·ƒ—Ñ©7–]òØÜ$ê2@yk×ÖÂj¿ “LLùÄI»ÎÕ)/¾KÅd<5?ùËc¥-½€A€Ëøúx™$˜OUÖï=#ð–È¢£iì |""ERÙ?÷œ¦*wOÇç°¾È-¥±+p/0’$þw¸ø®´X™ðâÜÍýWÇÊ}Ç'ãEA4c¾É~8QUÛÑí(ˆùœ{3â>ɺ€· À!À`r*›Kš;ÿ03ªlÈ.e²Ù¾±ãhì d1Ñ\/þÇYÅTåÁY 5Ú%4vn!óyNéÄß”p?Ç¢ÍN~p¤Ø'.žÉaÓÛÁ`±|â>Î*µØìŽJ| OZ¤ÿ9eô6î!d´Ø¶Vß7#Žªì»ÐÐÒ¥ó‹d+M~ññz㎳µTåÞŒ¸_ÎÔt›,4vî!´«¨No¶Þ>­g‚ ÏsÊ$|oo»g\¡PüynÏ©ÿ-)ÑV»ý—Óµƒlà€ÚRP5g\\Ìw,j–ígj}bãß F™4vÜoçëU:“cÑGÀ]”²¥ ŠÞ®À- @ÿLVÛ®sõ7§DR•ŸNW[I¹ŸÈH“ùCA%U¹yJÔÞâÉJcWà GÊš´&óÊITåÛü*ï‹Ç¥¯)è“Í–„…mÊï9õ_11Ül³í/i ±+p пÝEõ¾cQg²*m”DD¾ÐÂ;"òXe³ZñŽ€TÀ›!ß]TOoWàú »‹ê¯K ¥”4Zlvï°p[‚HÂBI‚øí|Ï©ÿâÄÐ]çà2 ºÒ–Î ª²ç|½XîÇöâÓØ „ÅáJý÷÷õ$(êÕÝx© !ú‘]ÑÌa1§GP•ÝÅE-ÁàŠ=Å=¦Eú ¸ì¬òf[ׇý8VÕ21ÄWÈ»8-`S—¾¦­KLoW0qppK§®ªýâ©?‡ÅL ÷Ë­B€Á @?ŽU¶¦EúS‹¹•- &Cèï?È&@/¡ŸœÍfåT´P•éQÇ*[il \BôeµÛÏ4tô b_‹Ã¡±+ƒÅúÉs*{NýÓ"ý‹›Ô˜-}]hê4YmC|©J^M×—\_.Ï«i§'†øÚIò\£ŠÆ–ÀÅ!@_gT\63!ÈDZH’ÄÙ†¯ïà[í¼|}‹•*«ýâ£ü$>÷lc½]€+C€¾Š”ª¸ëâÏF­JÛm4{ùÊèí .ËËWf±ÚÊZº‹ ‘ìSÔ¨¦·+peÐWykW| µXÔ¨f0/)B€«ãûHLÆyeÏQ?>Ч¼µ‹Æ–ÀÅ!@_ÕíÚ_1µXÙ¦á{y±¸xe€«c²XB‘¨¢µg‚ p™¸º]KcKàâ ¯šŽ^! V¥å‰Åƒ¬®ƒ#×tôõ#ýĵ*-IÒØ¸4„è¥ÛdQéLá¾"ªRÕ¡eŠÜS$®t:õ÷-¶V­Æ–À•!@/-AÔË ‚¨Sé9B!}ÁàŠ„µjµèø>:¾§—B€^Ú»Aø‰z^ÔÖmÀ{ƒÜ›ï¥ê6R‹Žïc»SÀBôÒ¡ëÔÝ&6!À=°ù¼.½‰ ò˜ †ã{ p)„èE¥3ñØ,êÕA›]o6³ùîÍçÛìö.ƒÙ±Èd0|\•ÎDoWಠƒÙæÅeQ‹:“•$ &Þà&XlA:³…ª¸lƒ¯€þ!@/f›Ëê &« &?'îÁb¿×¸,–ó"€3ü㽘¬6.»ç§Âl³Á`²Þ\ƒÅ$Âd±S‡é¼à !z±ØìÎWÌV;A \ pޏæˆnÓyÀþq‡^X &õ:‚ ØL&A$‰SI7a·¿×lv’ À¿Ð ÃtœýS‹A6„÷`·Û ‚à±{êp^p†½pY,ç«ÇŽ[¤דÝi³¿G7“Åî¼à ÿ:@/“$¡Ö›¤½]€ËB€^|…}g›÷ñ¬F„÷`5šD|5Pc4[lvÇ÷àRЋã­γÍË„|«óκ›Ñ(õœ÷_ú&gЋ㬱MÛÞ^½nà-À…˜õº`ïž×@;¾¾"Ü€þ!@/~"¾€Ë®éÐR•X¹Ä®Õ² ¸«Fë'¡k:´,&Cá#¤±%peÐ ƒADøŠkU=Gý_±!ÀMX»µ‘~bj±¦C"rXø5€þá_è+ÂW\ÝÞ+èu:O º>’4h»{…€öî_ñ [€‡C€¾"üDUm=!`¼BJÚICg'-ÁP5«Õ:>XFUªÚ50„è+Y!;ÛØA’ÇxsÙ,ƒªƒÖ¦àò *“ÉH ö¡*gTÉ Ù ›€‡C€¾&†øjjl ›É(5¨Tôv—eP©Âý$^œ‹Ó¶j ÍýÄ_z»W†}%+dLãlcÏ©J˜ÌÜÑNcK0¦öö”ОCþÙA0„èKÄãDÉŧêzBÀ¬˜@ms+Þ%èÒHR×Ò4;6*Öµy äbÌB€~̈Ì®hv^´Z­z pa†ÎN“Ñ<#º'dW4ÏŒ d„èGFt@^u‹Õ~ñÔ?.ÀG"àéš[èí ¡knöâ²'„\H’Dne‹s&¸Bô#=2@g²žWª‹ ±8Q¡k¬£·+DwCý¼8õê ²ÖÎ1=ÊŸÞ®ÀÅ!@?Æ+¤~"þþ TeIR¨FÙäx]=¸Òf×66.BUö_h”ð¹SÂühì \BôƒÉ`\—úëÙžSÿ… !6›­»©y­€.ºÖV³Ù²(±'ì„èß„›!|YrU|é—Ñ΀¡@€¡zeùÔüšVçY„__™jÒu·ÓØ•§i/-5j4oÞœFU–(–(ÿº<…Æ®ÀM!ÀPÍŠ \õäæ\“õâ©ÿ¸ïgæ'·œ4ëtôöæ!,Cˉü?Ο@½.Èj·?ö}öò a W!®À[«Ó›ºôé9õuÅÔH™¨ñèQ»òÊœìPo¯¿­è9éÿ,»¤ªMûÎ-4vî !®@¨TôØÜ¤ì:ÕÞ}ñE‚<6ë·ÏP7Ô«««èímÌ몫k¯ªþàÖ ›å¨têÍÛQøÐì„h¹„ÞÞÀM!À•yié—ýÔ¹Te^|ðC³•YÙžÆÆÆ6«Á¨Í*¡Šëf'Þ3=®öÀ>S—†ÆÞÆ“V[³ï·;Rcž^ÐóR€MÇ+¾”ÆÞ`l@€«÷¯U©1þ’›>Þ«7[—½ïÉ¥b»¹fÏo˜NøZ¤½fÿ>®A·ÿ©¥>×Q4Ym7¼Oá#|û–éô¶cB\=›õó#‹šºô÷}u„*ûv<²ÈÔÑ^Ÿ›CàY«Õx,OßÔ´ý‘…¾bªxÿÆ#ÕíÚ_»Ž!p-àš„JEŸ¯Íü¡ òƒCç©â”0¿më¨ËËóóhìÍ}) N¶ÿ‡yÓ£¨â†œ’oó+>Y3+ÜC`x°^yåº{÷6.À›A0þòó‰©~±þÞŽbŒ¿÷¤ß/vçYM&I(î^_¦‚ÂÖS§~xpþªÉ‘Tñ@IãíŸ|añ¤Çæ&ÑØŒ10 æŒ jë6üyÛ‰ùñŠ©ÐQŒ ô —‰¾Ý—O’¤88˜ÞÝEó™3M'O|pûŒµéã¨â™†ŽÅïîºmZÌ{·á0œ˜â †…Åf_þÁžóJuÖs+"ýznc‘[úÀ×GåII!éƒÆÝ€òĉæÓ§Þ¿mÆ£™=§û jݬ7¶GøŠ÷<¹„zkÀ°@€a£5Z¼½³½Ûxô¹ë>Bª¾ùd埒ÆÄ„ÍšÍ`bJ?H’¬ÏÉé(¹°aÍœ{2z®´j ³ßØáÅezæz—Æ`LB€á¤ÒU7Šš IDAT™2ßÚa±Ù<{½¿Ø‹ªÿz¶nõ'û½Ã,dq84vè‚ìVkíÁÚ††ïîŸwÓ”žqj½iî[¿-¶£ÏõúË.0Ìš5úÙoì`³ûŸZì# êÇ«[—~°Çʆ/¾Ž+²b1èkÛKj»v<ºhvlUoÕ¿»«SoÎzn5Ì`x!ÀðSéLKßßÝÔ¥ßÿô2êy‚ Ê[»½·»Yg Ÿ¿@4È<„®¥¥öÀ~—±÷‰%‰ARª^Ù¦YðöNo/îž'—JƒìàZ Àˆpäe§~÷K’‚{ozó]_Ú]T¯HK÷OOc‡´k»Pܘ›;w\ðwÌóñ©ziKç’÷vK¼ÝO,Á]Q0RºM–›>Ú—_ÓúãC çÇ+¨:IÿÚsêåí'}ÂÂBgÏaóùƒìdL²™LõÙYªªê—–N~åú&£ç©‰£åM«>Ü;1Ä÷§‡y{a$ Œ,„A›}ݦ¬¯óÊ?ºsÖ}3âœ?Ê®h¾óóCíF›bN¦$$„®GŸ¶©©ñð!oñÍ}™sãzMŸ°éxÅý¬N‰Ú°v—Ç(`Ä!Àˆûû®ÂÿÛ~òÑ̤·nžî|lÓÍ}ŸûM^™oì8EZ:ÛkŒ_°šLÊãÇÛKKnI‰ùèΙÎüYíö¶æ¿}àì‹K¦¼ºb**À¨@€Ñ°ç|ýŸŒðo]·Ðy*!‚ vœ­}ð›ìN“- -Õo\1&€$ÑQQÖrü¸ˆÅøèÎ7:ÍLDmG÷Mï­lÓ|sß¼eÉatõ!FIIsçª÷ªt¦ÏïžÓçPש7ÿñǼ/rKD~òàŒ Q@À@;qGº¶6en޶µõδØwoÉ yΟî-n¸çËÃ"gÛà ÇËèj<BŒ­ÑòÈ·Ù›òË™“ôÆÍi^œ^ïÃ=^ÝúøæÜ“5­²è˜ ”©)Ôï½[§ÏŒ tþÔdµýù§üwœ»%%úã»fa Œ>„m›ŽW<òm¶B*ølÍœŒè^'ý$I|²âÏ?lPwûÅÅùO™Ìºåks-:}óéÂŽ’’ oÁßWL]“Ëì}›#¿¦õG«ÛµïÝ–qoFÜ@ûQ@ƒêví_9\ÚôHfâ?W¦Šù½&¶“äÖÂê~>QÓ¦ñ •O–(íÊÕèZZšOŸêª«÷“¬_5í¦)‘}ÿ:“õ¥_N¼¨hFtàgkg;O¦0Ê€$I|u¬ìÙó\ö›7§ß25ªÏ f«ýëãeë÷ž-kîô –%%ú„G¸ìû‡H’쪫U/îllˆôó~~Ñ„»§ãsú¾ôoÛ©ê?nÉë2˜×ß”vÿŒø19ÜBЩMküÓOÇ¿Ì-›øî­C|û¬@’ÄÎsuo8w¤TÉzùÄÅûÆŽãI\h¸€Y«í¨(ï¼PbÐuψ ~fþø&…3/9¼)UOm>v¨T¹&=öõS10¸„ ß©úö§8–]Ñ|gjìKË&÷{…¼¦CûenÙ§¹¥JU·ÄÏWéáåKÛpz£Z­®©é®©Ö´µøÈwoF\´¼ŸtRÝ®}mgá×yåi‘þoß2}Z„|ô»èB¸ŠŸO×¼üËÉ’æÎ»Òc^\2%Æ¿Ÿ*IyÕ-?œ¬ú® ª¥S'”ˆ„¡a’°0Q` ‹3â£ëm‹®¹¹«®N×P§ëÒúI·¥DÝ:5*#:àÒS‚ ªÚ5ÿÚ}ú«ce1þ’WWL½ir®ÿ€KAb'ÉÍ'+_ÙQPѪ¹aRøN˜8К…uí»ÎÕo?WWXÛÆ`b™Œ(”˽¤2¾Ô‡Éf÷»á•õc³ÕµZßÚfjmÖvt$11ÔońХãæEÈû=ö‘_ÓúæÞ³ÛNUGøŠÿº<åŽÔÇp9àrlvrkaõú½§ jÛÓ"ýÉL\ÕgRg*éXU˱ª–Cå-§ëÚõ&3ƒÁJĉ„-’p%b®HÈæñÙ<>›Ïgq9 &“ɹø<‚Ýb%í6›Ùb5­F£Õh²tëLZU«µj5Ý i'ùî!ÜÆÙÕw'*¾?QYÓ¡ •Š%†,J ™Ÿ|¥Gîk¤Ö›–(÷7ì-nptrë´¨;Rc&‡úf×!Ü I'j[wž«Ûu®¾°®$ÈÄ éŒèÀ™1Ó"ä±þÞÃ>Ïf'+Û4'jÚr*›³Ê›‹›Ô$ANõ[2>tYrXZ¤ÿeo¸&„pc­ZÃÁeneKnUó™z•ÕnçsX‰AÒd…,.À'Z.‰ñ—DË%WônÑ\Ù¦©lÓT´jÊZºÎ5ªÎ+Õ‹•Åd$+d3¢3¢æÆyãš?¸=„#ºM–¢Fõ¹FU‘RU¤TU·kÔ:‹ÍN—Í” x2!O*à ¸ýû,A‡Öjµ‡wþ¢W×6¸„ðDT˜8q"AŸ|òI¿«9uÛ¶ms.¦¥¥qôèQçbee%A±±±ŽÅýû÷_ýõÎwø|~Ÿ=÷ùrCÙó@MöY2ßñ»D‡Ã1›Í›7o¾ýöÛûýÍ¢ŠŽ=÷Yç²{î÷ÏÒgWŽE£ÑÈãñu&“yi…Á`Øív‚ .Û-ŸÏ7™LjµÚÇÇÇQW«Õ2™ŒZáêÚW€—ᜈßs6›Íf³Ùív»ÝNA- A¯¾ú*I’ëÖ­+--5 $Ivwwå ]vÏCç8ÞNƒûT¨=_u·#Ñ6Œ2„ðhŽkÝ¿üòËÐ7IJJ""??¿ßkkA8®„¿þúëãÆãóùA8p ÏNGb«ÕzE{ —í6""‚ ˆììlª’““C{Û0,À£­Y³† ˆgžyæ¿ÿýocc£ÉdÊËËë3´¾ÇÀº+V|öÙg555ƒÁd2•••}úé§A„††±~ýz•JÕÙÙ¹eË–|°ÏNw¶lÙb4‡¾ç‘pÙn—/_NÄO<‘••¥Óé²²²žxâ çhi†ÇFŒ-ÎΟ? ß‹~GüñA~¡Ö¯_ß§¸víÚ>»ºçž{úýŠƒï¹_}>½tåÁ+—í¶¥¥%00Ðy…n¸ 6›=Ä¿pYøOD…’$Ífóo¼1aÂ>Ÿ/ 333·oßîXmÃØþýûo¾ùf…BÁáp¼¼¼’’’žyæ™Ó§O“$iµZßxãØØXõ·¿ýº5NmÞÙÙùðLJ‡s8œ> ²ç~]cJ·eeeË–-2™ìÁ,..&B.—ñ/\žOD=0eʺ{q?|ðÁã?ž™™yèÐ!º{€k‚1p+W®ÌÊÊÒh4MMMŸ~úé‹/¾HôžHÜ®€'•€+ré[SRRrss¹\.-ýÀpÁ•¸Œ;w.^¼8((ˆËåFGG?÷ÜsDØ—_<ÛÒ¥K—.]Jw0üp%ÀC!x(„…à¡<B€‡BðP !ÀC!x(„…w€G°Ûí555Ôb}}=A>>>T1,,ŒÍÆox¼J<I’ÑÑÑÕÕÕ­àïï¯T*Y,Öhv@/ÜÀ`0n¿ýöNôÙlö­·ÞŠžWÀS”””$$$ ôéñãÇSSSG³Ú!€?~|qqñ¥?óáááÎ#<n€Y»ví¥×ü¹\îš5khé€^¸¤¾¾><<üÒŸù .ÄÇÇÓÒp%S¯²Úí|+1Hš¬ÅøDË%1þ’h¹ÄÛ‹{é¶[·n½é¦›.­kŒæÊ6Me›¦¢USÖÒu®Qu^©6X¬,&#Y!›˜07.8È[0ò>€‘…n†$‰µ­;ÏÕí.ª/¨m' 21H:#:pfLà´y¬¿7‹É¸ü^®„ÍNV¶iNÔ´åT6g•77©I‚œê·d|è²ä°´H&c˜¿"Àè@÷`'ÉcU-[ ª¶V7¨u¡RÑâ¤E‰!óâƒ}…üÑìD­7,Qî-nØ[ÜPÓ¡ öÜ89ruJÔ̘@¤p/àêÔºÏsJ?Ï-©íèŽ ð¹ejÔꔨd…ìŠv¢Ò™T:S‡Î¨5ZÌ6›ÎduÔ\6Íó92!O&ä]iž(nRo)¨úádUq“:D*¼oFÜ}ñá¾¢+Ú ]Àu(i|çÀ¹ÝEõ>wíôØ{3â&†ø¾ IUíšÓõEJUe›¦¼M[Ý¡míÒñçœÁ ü$‚(_I¬\%'+d“Bü¢äâËžâ)U_æ–}u¬L¥3-J yj~ò¢Ä\‡.Çf'·V¯ß{º ¶=-Òÿ‘ÌÄÕ)Q^œŸdQéLǪZŽUµ*k9]ß®7™ †P"æH$l‘„+sEB6ÏæñÙ|>‹ÛÏ›Ùb5­F£Õh²tëLZU«µj5Ý i'\àÚ!€«øùtÍË¿œ,iî¼3-楥Sbü%—®c¶Ú÷—4üp²jÛé­Á,–ùx)B%!!¢À§Ÿç‡—ÍbÑ5·h •JÈ㮜~ëÔ¨E‰!r¸´é‘ÌÄ®Lí3'¿Áb}ï`Ñú½gµ&«,.Þ?9™ëJ§þƒ³ôíÅ:ŠÎ ØÌOx|îxÇÛ (:“õ¥_N¼¨(#:`ÃÚ9ýÞû0Ú6¯xäÛì`Ágkg÷üO’Ä÷'+^øé¤²Sç0iW(¤«ÏkaÑë›ÏœQ]¸à/áÿsÅÔ5é±}nä×´ÞÿÕÑší{·eÜ›GWŸàá`ôh–G¾ÍÞ”_þðœÄ7oNïóèÿñêÖÇ7çÔ¶Ëãã&Oæ¸çáߙŠo9uº½¸xb¨ï{·Nï“xŒÛŸÊ÷à¹Õ)QŸÜ5»ß·Œ(„%%Í«>ܫҙ>¿{βä0ç:õæ?þ˜÷En‰B4}º—ôʦvqÆÎΦcÇÔ õw¤Æ¾½zº\Ük®¡½Å ÷|yXÄãl{xáøà1õׇ£á«ceë6eÍŒ üîù}fÜÛq¶öo²µV2(c†42’®GZWmmcN×n}guúÝÓÇ9ßèÐïÜpðHYÓoŸyß Ü€Ñƒ#‹$‰WwüíׂG3“Þºy:—Ý3‡®Æh~ìûÜoòÊüââié,Þ¿n³˜•ùùmÅ®K ýêžLçKV»ý…­ùo8û§ë&ýã†T<5£!FÉj»ï«#[ ª>ºsVŸsÜìŠæÛ??Ôn´…ÎÉ”„„ÐÕáèÓ65Õ:$bÚ¿½oî‚…óG›ŽWÜ¿ñÈõÂ7Þ—9È»† BŒ•δ⿿oRýøÐÂùñ=G;’$þµçÔËÛOú„……ÎžÃæ_ÙÛ{Ç›ÉTŸ¥ªª~iéäW®Oq~pàhyÓª÷ÆÈ½}ìº>£†BŒˆV­aÑ;»T:Óî'–$K©z§Þ|Çç‡~+ªW¤§û'§±CÚµ](nÌÍ3.xóóœÇI”¶t.yo·‡½ï©eÁ>˜XFB ¿ªvÍüÿìñ8ûž^êÂç·å%Jç]¸§ פH©ºsÃÁu³ÉL¤ŠyU­wn8ì§HM§±7÷œ2Õf2ß»ñH¨T4gÜÅçï›W¤TÝýå¡h¹$%ÜÞ`lÀÓpõt&kê¿~òØGŸ]Áç°Ų–®Ô×fE.Xˆ‘€W$j4ÔÕ{aE²ââ+†-6ûÜ·~mÕN¾¸JÂÇÃp­00®ÞÓ[r[4†­ëR  Ûd¹áÃ}6/aXf&À5a¡³f³¼½W~´¯Ë`vÔ8,æ–‡hŒæÇ¾Ë¡·;à*}¢ò³ì’oîŸKÍgG’Äퟬգ–,eqpžz­˜lvÄâëšôÖ?êy. È[ðõ}s7¯Ø˜WFo{0 ÀÕhÖèÿ>羌øë’B©âöŸÝYT’9—#Àko†ÇË+lÞüÃeÊì>E&„<š™ôäæÜzu7½À€Wãñïr%|î;·N§*'jÚþôS~ð´ižaN¢À@Ezúß~-È®h¦ŠëoJ ò<¼)›ÆÆ` @€+¶µ°z멪/î™#âqÑ|Ó'û%!!&ÑÛÛ˜ä?~¼42òæO¨t&G…Ïa}uÏÜ=çë¿9^NooàÖàÊh–§8¶6}œó+ïžÝz¼Ug ™9‹ÀXÀ‘’1£ËB>ñC.U™!ÿÃÌ„ç~<®Ö›hl ÜB\™¿ï*4X¬o­î™à`‰ò³¬ Š™39xAðˆa{y…Ìž½)¯|ç¹:ªøú© ñÊŽ·†W ´¥óíýçþµ*ÕWÈwTºM–µ_–EFI£¢èímÌó ó{ïÆ£Ô©¿·wýMiÿ=|þlƒŠÞÞÀM!Àøã–¼‰!¾÷͈£*¯í,lí6OŸ>ÈV0\‚ÓÒºL¶ÿÛÞsêgjìô¨€§œn B UVyóÎsuÿ¾1ùû,@e-]ÿ9p.0e7FÇK˜šúá‘â"åÅSƒø÷i‡Ë”{‹èí ÜB IÏþ˜·d|è¼ø`ªøøæ\/©||yy|‚Hî÷È·=§þÑ«&Eþù§|ÌW !†dWQ݉ÚÖ×VL£*J÷ž¯JKg`zàÑÄ ÓÓ³+”Î#_]1õt}ǶSÕ4öî!†äµ…×%…R/¯#Iâùm'|#ÂŘhÔ‰}£¢_øé„ý÷sÿ¤`é “Â_ÛYˆ‹pEàòŽ–7¯n}iéªòÓéêSumÓRiìÊ“Nv¡Iýý‰JªòÒÒ)g:02®B\ÞúßÎÌŒ ̈p,’$ñ¿Ê¢"ùR)½y,ž·DóÊÎSÔÅ€)a~‹CþýÛiz÷‚—QÖÒµ»¨þ©ùÉTe÷ùºâÆŽ€))4v“§T¶vþ|º†ª<5?ùP©òLC}M€›A€ËøðHq¸¯h太òÝg¤áá^¸ @+ž·DùÚ®žSÿë’Bƒ¤ÿ=|žÆ®À½ À`ôfë¹êQÚ„ IDAT¥ÍN`1/>p¼º5·¢É/9yð aøO˜xº®íp™Ò±È`ëæ$|›_¡1šém ÜB æÇÂ*½ÙzÏôž)?:zAì+²Œ\îàÿ¿#¨Êš´q$I|—_9ÈV„Ì—¹eË'„H¼‹j½é»üJiB"½]EšøÓéêV­Á±è#àÞ01â«ceôvî!T§ê>\¦t¾ ð]~¥AÈbbhì œI££˜lö×yåT垌qǪZÊ[»hì ÜB hkaµTÀ».)”ª|‘WæÁâriì œ1YlïȨ N§þóãþb¯-U4vî!´ùd劉á\öÅ’òÖ®“Õ­²qãèí úÅŽ»Ð¨:×xñ•B,&ã¦)‘›ObX\Bô¯Y£Ï¯i½qr$Uùád•—ÀKŒy‚]‹( P(9õoœy¶AUÓ¡¥±+p п]çêùlö‚„žCþæ‚jQx^är„0<ò»“=oš3.ÈÛ‹»ë\=M€[@€þýV\?{\ ‡íXlPëŠÛ}""ß h!ˆ¬jí¤rX̹qÁ¿#Àe @?ì$yà‚rQbUÙUTÇfsÄÁA4vðø<ç— /L9\Úd±Ùiì \Bô£¨QÝ¡3Îï¹°³¨^Ä`±hì Â`0„ÁŠ]E=¯œŸ¬1š ëÚiì \Bô#»¢ÙÛ‹›¬9I’8\Ö$ |+ ‘X¡Èªh²Ú/žúÇøJÙÍôv.!ú‘[ÕœåÏü} àù&•FoÒÛ Bd4[Oý§GûçT"À` Ç«[Ó#¨ÅœŠ.—ã%ó¥±%_âÃðs*Z¨Jzd@^U+-€ëC€¾:õæÊ6ÍÔp9U9VÝ"ô—ãá@—Æ ò€Üªž0-BÞÔ¥oêÒÓØ¸8„è«H©"IbBˆŒª¯içùùÓØ _.ϯí¹01Ä— ˆ³ *ú:W‡}iè xa2‘cÑlµW´tzÉdƒo´ó’Éê;4£Ù±(ò>Â3 ôv® !ú*nR'I©Å Íj«Íîå‹®ÎËWF’Äy¥šª$K‹›Ôƒl!úªjÓÆøK¨Å ML“ïíMcK0<‘˜Ía—4wR•IU»†Æ–ÀÅ!@_5Ú_1µXÕ®HD &~T\ƒ!ˆ«ÚzÞá+®i鈴#pqø—z!ɾ! ¶£›#ÑØ’;*˜Ê(˜JÃÃ,‘Øùå¾âÆNÉjýNÀ- @/íÝF£ÅF $¢ªCË"¸¶H\ÑÞÂd";Iâ)ABôÒÖm Â_§*]Ž@H_Gp¸RÓsÈ÷{Ѧ5Ò׸4„襣ÛD„ŸˆïT1²ùü·ÂæóÕÝ=‡|Ç÷±C‡ýC€^:tFƒðöõÕ:zB€IY]ùÇ•§f‰ÎÌ÷«û×Ãv£¾Ïö~ï»_ZTíú¦ìÁÌÓ™>…ÓyE+cÞ{ÞÖÝ5¼;¹´Õkü³_56Ÿßm4Soó9\6Óì.Ŧ»p-z³€Ëæ°.¦C½Ùj±ÚØ<Þ(·aíê({`¶¹µ »A×¶õ#‹úʧÁ'Éê—ïRíù–*˜*[6¾¡ÉÞ÷E.K(dÓ¡ïdxZ&,>$‰N½Y.¾˜Û|¼x„è®@/&«ÏF‹ &k´ÃbËWëÍ­ Ü ðqŸž|T;îãCúâ“Wº“ö_6¨ö|ËñWD½þÃÄým“sôñŸç §ªÎ7þÏáÚɰ´:\˜l6A‹•ªð9,Ç7àRЋÉj㲙΋A0X£ýsÒyt;AaϽ/ž2‡)‰S2CŸ}÷JwÒþógADýã;é‚Õl?&ÏK8az俾'B}hÛpídXZ. &‹øý»æÀc³ðˆ · ³ÕîÌV;AG0)« ‚MžEUÄSæ\éN ç‚({h.A$AA$A’A˜•5õ“aiu¸0/ \6!‚½ØH;‹Át^$‚ášWŒŒ‹Çãßßql7z­@’Aö~¤Õ2œ;qLA6;IXL†ó"€3„è…Ëb™m6çEb€CàˆâGkJºOeyϾÞQÑé³G`éh65Õð‚#•îSYÎ+ð£“ôÅ'ã7æ § ô…®}'CiuÔ8¾S<6‹ª˜­vÇ7àR.y†ôá²™Ž[Ô"Av»}à-F„ÏìAÔ½ñ¸¶ðˆ]ß­-8\ÿæ“}ÖáG%ÑðæSæ–z›^Û•½³öµœWð¿ù‚ *Ÿ^ÑþógfeÝd Í&c]YûOŸ–Ü—1\;J«£†´Ú‰KBƒ_sè®@/\ íp÷óª=ßš›jËÌtT|æÝhn®ëµÎšgµ'vÝîšG„ߊûÚ·N­à»â^}é©ÖÍï×þý~¡kÞÉPZ5Ž+}†v:gg8E€^¼¸,ƒùÿÙ»ó¸˜öÿà§YÚ¦}×¾/ZѾ¡ÍEE”ÙÉru¹÷‹p]"×Í^ÝP‰È’V*mJ¥R¡¢´KËÔLË4Í~~tI²Wgš>χæ3gÎy…fÞó9ŸåC À‹áâ‚Xôñ¾ù×ü7[ÄÖŇÉI¸mP99ìa˹ʯð*ksa°ÜÒ ²›+þ/dØ1 »Ïj^LµwÇJÉqa°(>>U]éå;§Þ(­“|KÔqäÑ!àÁ¶ôÓ|XPë02.ƒ†€’_5Í;—Ü´F÷¿¡ß®‰›Kèh# ‚ Uüfÿ±ŸE¨~Ûô$“~á¿; ‹gKØ­öîÓU‘ {=ÀG>]m^ÇË €Åç'•"Ì7tÉg †‡î0(€ˆ ð@Ô1dq/ƒ Š€‰A¥ˆ |XãyàßqèNC"øÈÀæ³m=æÊ«ˆãè$r‰€ï@ë!)‹ >lë%Cÿÿo ð)PàÁJðÖvô ¶¨J2I=_xɸ™Qƒ_ÆìëQ—|X‹ïåçÆ€"€ÏE0œ²¸`C'ièCjè ˜h½½*Š€B¯’¸×ð­’þŠ`8 ÁºŽÞÁ‡ªB …IÛѲ;ƒÑO"«I~Ø"¹¾ƒ$Ï à³@ §&)TÝÞ=øÐ@^ ‚ 2¡¹DÀ7é'a6l©¨—º×CVVÖÅÅÅßß?--­¿¿ÿ g`²E0œ¡¼xeK×à&ôr"8o?€l*à«ú ^nŒêÿ `ÁpE;ië_ç¼½½I$ÒéÓ§%$$lmm÷ìÙsÿþý÷ïß#ĥĀá äÅ,Ve+qš‚Ä@‹®¬èÙTÀWQ-QÔÿxÛÞCf¡V-]l¢,9ÐòþýûÜÜÜœœœ§OŸž={–J¥ ›˜˜XYY͘1ÃÚÚZTT¹ø ÀpšÒÂ<ô«æE€¥ŠÔË¢&dS_Emo³Ö‘|øê=ÅÅ5uʇÏuYYY‚ètú‹/rrrŠ‹‹cbb>ŒF£µ´´f̘1PL›6 …=…Àá@ ‡A¡ åÅ êÚWšk ´X©KŸJ-cR©hž/¿@ ‹ÁèÁwX¹è ¶ÔµO"Šãùw‹Å|Þ<¬««ËÏÏöìYAAÁíÛ·©TªŒŒŒ™™™¥¥¥µµµ±±177÷xüŒ/P#°Ñyüºyð¡•š õµ· )( ˜ ø‚><žÅbY©É ¶<©nµV—ùÂK†RQQQQQY¶lA4­´´´     àÒ¥K~~~|||&&&666VVVVVVBBB_=!èîF`¡*ý²™ÐC¡ <”àU’îmmE6ð¤Öœ¢ØËRèÌçVêÒ?p*nnnSSÓ_ýõúõëuuuÝÝÝqqq™™™nnnÂÂÂjjjÞÞÞ!!!ååå`2˜Ð@O0sU)& ~V‡wБhqÕW¸ö¢21A6ð9ä¦Fýý4E x*ƒi¡ú#EÀ0BBBuuuåæææææ>yò$&&†B¡¨ªªÎœ9sÖ¬Y3gÎTRRúùË0ž@Œ@N§'+–ôªq°øEWá\Æ+z_‡C6ð)•ÒÝŽŸ³Àp°%éU£º”ÐÐ…ƒF…ˆˆÈüùóçÏŸA•J-,,ÌÎÎÎÊÊÚ²eK__Ÿ’’Ò@A`kk«¦¦6º—`,€ÛÀÈæê)$¿ú0#ÀVc îy÷ÁHÀçô¾kFA\vÚ²ƒ-ɯš~ÑÛ<<<ÖÖÖû÷ïôèQWW×Ó§O7oÞŒÇã}}}ÕÕÕV®\Z]]=¦1ø F6WOáukW þ¿­ƒp<˜_tºëjMŒ¨«¶f––¬(ÿs7š»úÊÞuÎÕ¿Qœ ÆÂÂÂÏÏ/))©§§§¦¦æÀ\\\GŽÑÔÔ”’’Z²dIHHH]]ݸEà[€"™¥š´/wÒ«ÆÁ–e&jÝMï`ÝY6äѺ›¼L>t¿'¿jâÅ`fjÈ~áUcJUUuãÆõõõÏž=Û¹s'@ðõõUSS300رcGbb" ìO lÀÈx0è…FÊÑ…¾úÏ×WÄ¢Q]õ ¦>ÕÝÐÀÁ ”[n¾u6PüÜ ã F›˜˜ìÝ»7--@ ¤¤¤Ì›7/''ÇÕÕULLÌÆÆÆßß?''‡N§#&)PŸå>]%¯¦µ‘ðß76A^¬«¡RWõdSë«æè*ˆáþ»ÐÖÓŸUÕâ1CÙTŸâããspp8qâDaaaoooRR’••UBB‚­­­°°°££c@@@qq1Ò1`rE02™äëfÇ[[x¿¤~°ÝÇV§»µ­¿ì(È.¨ÝÝÝÍÍ›mu[bKëy0èñðøùù ‚¢¢¢ÚÚÚ3gÎ;vÌØØXOOo×®]iiiT°{5Œ=.°Ö0TWW×åË—Ï;×ÙÙ¹|ùò.ÍÙ54¾Ò‹ž…aHõ@4YZQÁÒÙœÀ€æÂg\uo›Ž/C£þÛ7È" VE\èÆz;dƒý‹URR’––––––™™ A™™™‹‹‹ƒƒÃôéÓ¹þc$Fè þSYYéíí-##sîܹ={ö´µµ………íõœSö®óiMÛÀ1\\ÐzK­î·Õ,:Ù´A0“Ù]UµÚB}°(iêȯm÷™©óå²' 5cÆ ??¿ÔÔÔ†††àà`YYÙ'NkiiíØ±#--F£!8 ((--ÍÅÅEOO¯¸¸8$$¤¶¶Ö××WXX‚ eÉi ¡9•ƒo™5Åbá_W~þ|À8é¨zäR}íô[þÍy­3EÄVc ‚©F…¬¬ìÚµkoß¾Çãsrr<<<222%$$ÜÝݯ^½ÚÖÖ†tFà ˜¼`NNNž={¶££ckkë7ÊÊʼ½½y>Þ*p•fLq-¡ï¿´¢ü<ë­´:_¾€Y,$Rÿa¸³ìÅ 3 i!¾–^ ýƳ·ÞæšÈ] ÆÊÊêØ±c¥¥¥x<þüùó(Ê××WFFFMMÍ××7-- L.€Š€ÉˆÉdÞºukúôéóçÏçççÏÈÈ(,,ôôôÄ`F˜T¶ÎJ›ƒ9ŸQ>Øò«.¥L¬©ÇÈÀp]õõäÞžöήd²`Û©¦SÞÞÞ·oßnnnމ‰±±±¹qㆣ££²²ò† CMOVl …Æ`ýóøåZ+-~nd³AAAww÷k×®áñøW¯^mß¾½²²ÒÍÍMHHÈÚÚ:((¨ìx ß“‘Hô÷÷WRRÚ¿ÿÂ… «ªª‚‚‚¾q——Í3§ÉÔ›Ï>,tØe­¿¯³ªjÌò_Bx[CééýÓÕx°åÎóÚÖò¯³õ¾ð*ޤ««ëçç—““SUUuâÄ †wîÜ©¤¤4wîÜÐÐÐööv¤[S9ßû÷ï®^½ŠÁ`¶oß¾mÛ6 ‰ï=ÉÚð¬Ìª÷¯{rcþ+ׄgÝ~õ^Ëc íÈÀ—ÀLÖ›»1Î’Ñÿ?É‚õÄÊ‹ß\ol6v@$ÓÒÒâããccc{{{§Nêáááéé©£3!'MÀ˜E'Ããñ'Ož¼|ù277÷¶mÛ¶oß...þc§j$4Ü:ån6ø]ó}YýÀ-Q}ƒ)3fŒ^dàëZËJ;Ÿ?¯:ºDAT` åÚӪ׳+/õ½ƒ'´îî¤ØØØääd‰4cÆŒE‹yxx¨««# ظÀ™:;;÷íÛ§¢¢yèСúúúÇÿpA¢˜À:k­KGÈŠðïûŰ½¬Œv‚Gt2_Rò»£þ`À`±Ž?,Ya¦*€a„……—-[vëÖ­öööøøx##£3gÎhhhŸ:uª¡ì‚ à8---›6m’““‹ŒŒüûï¿wíÚ%((øógþcîôî~Ú™´—ƒ-; $p<-……?rൠñ`öÌ1l É~ÝH tžŽ`*6ÇËË;þü!¯^½rpp RVVÖÕÕõ÷÷¯®®F: œ£­­Í××WCC#>>þìÙ³µµµ7näæµ±â²"üÌþgbIñ¿¯þ8̹¥ÕÕ=ÍïFë*ÀZZ;Þ¼þÛÝ\ˆ÷¿Öå w;*‹B7èêêž8q¢±±ñÉ“'¡¡¡šššÕ@m-˜õ L:`L' 'Ož¼pá‡Û·oßúõëq8ÜX\ˆÆ`é¾m¥&smõ¬ÁÆ%¡i‰oÚµÜ=PXìX\Àb2«ïÞ±S}°Ùi°q˜ė¯,áÃ"¿qðDD§ÓÓÓÓoß¾ÛÝÝmggçéé¹hÑ"QQQ¤£Àx=[___@@€––ÖÅ‹}}}+++}}}Ǩ€ ˆƒ:êjr½ :¿öÃÌ«<,Ñ Úû¢¢1º(0 õùs&™|vɇ­›Jš:BŸ¼>ìb *€†ÅbçÌ™ÖÚÚ/''·{÷î)S¦¸¹¹Ý½{—B¡ Æè ˜¨úûûÏž={òäI‹µwïÞ-[¶ŒÊÿo±àâ£×­]¥~öÜ+©sNUsš#¬¤4>&›Þææê¤¤+Þ3W[þ·*0Á2þ람ÊoóÍÆaX,VzzzDDÄýû÷ †ƒƒƒ··÷Â… ± £ àD '`âa8::ÚÀÀàÀK—.­¬¬ôóó· ‚ sK­ZºÉ‡ãŸ¶,š¦²ÂLóÝ“,z?X·uô1¨”¦¬L÷ªƒA'–¾mï¹èe`0Ž„B¡"""ÚÛÛ#"" òòò’‘‘Ù´iSNNøÖpPL$0 ÇÄÄL:uåÊ•vvvµµµ.\‘‘çŠbæOÿ;íEQ~°1ÈÓB”Ó”•wÉÑCMÙÙ8.øÂR«Á¶Wï Ç–ìýÅH] L +|||ñññõõõ,,,´±±QVVÞ»wï›7oN£Ü˜0222öíÛ÷ìÙ3ww÷#GŽhkk#†ÃNÿ$Õvô”X<8R½ì]§ù‰"S§Ê™™#˜Ã¼/*êxQ–ý»‹¹ªÔ@ ™Æ0þëž?oæ.g Ôñã†á¼¼¼ëׯߺu‹H$Μ9síÚµîîî|||HG€ÞA&€çÏŸ;::ÚÙÙñññåååݾ}Ù ‚ WøšY½úö觃†òâAžm/^tÕÕ!˜“t75¶–”œZd6X@´3&¯­§ÿæ;PŒ'...KKË‹/¶´´Ü½{WPPpíÚµS¦LÙ¼ys!X*˜°À›[kiiÙ°aƒ™™YcccLLLzzº™™Ò¡þ#'‚»´Ü:<¯êVч…6Ú謷ÖiÈÌ ãñ_x-ð-ú; Ó½LÕ}í?l ô ¬>äIe§åàŠÀ8ãæævss‹‹‹X–»  ÀÔÔTSSÓß߬BL8àv›¢P(gΜù믿ýýý×®]‹Á°ã4°ßcò/f•çîY0]ñ¿M‰X0¼èrêÃ×­ ð #oâ¢õ’ÞÆÅZ)‰%mû‹þ¯X¯h!š]e¡y~™Õ—_Œ§ââ∈ˆ¨¨("‘hgg·qãF0›˜(@ÀvX,Ö¿ÿþ{øða‰´ÿþíÛ·³óMG‹eÿwâûî¾Â}‹w²ï¥Ð­NÅב™jÎ.^^dNDL*­&1^ËÊß³`ðoµ‡B3ý+VB€7ãwçÁ²`===ÑÑÑaaaÏž=SPPX½zõÚµk•••‘Î_ÞJØKnn®™™Ù–-[œ_¿~íççÇÎAêúºÙ]dÚªkLÖ¥ /6Å÷ 4³.9‰I¥!›pÂaÑéõ’…XÔTß¹ƒ C"³Û{û#×Î{Ú¸qcAAAccãÖ­[#""TTT¬­­cbbèt:Òé`dàÝ„]444,Y²ÄÆÆ†ŸŸÿÙ³gÁÁÁS¦LA:Ô7QHÞ>÷ñëfŸ¨'ƒ2Bü™;œ”úGÉLðøÍXLF}Ê#,¹7s‡óлþ¿ßÉ‹+kˆÛ:GEìÀîüüüªªªnܸB¡–,Y¢££ØÙÙ‰t4È#‘H{÷î:ujqqñƒ²²²¦OŸ`;Â+I^ñžu%÷Í…ÌòÁF%qÌó±äÞÚÄD•Š`¼‰‚I§Õ%%Ã]„Œó‡.–ûúŸÇ/CVØZ«÷šÀãææ^¶lYvvvuuµ»»{@@€´´´‹‹KZZ¸ °0&a<صk×û÷ïwïÞ½{÷î±[öœN}áw¯ ríìe&êƒÒ¬¿Ûé\ªóçqãÀ€öÏ¢÷‘k“ÅPÌÌó‡~Ý¿_R¿$$ÍßeÆó¦!øIT*5...$$$--MKKkÍš57nÛˆEbêêê¶oßž˜˜¸|ùòãÇËËË#hN(>šøüúZ»¥&jƒu@V™;—Ì µ··îa²(3sç|5É}ñ/_NýÝÑป)‚ñ€Q”——wéÒ¥˜˜~~þ5kÖlÞ¼YMMíë/€±n  ¯¯Ï××WKK«½½½¸¸822’3*‚9Ïð±ºúZæÃò¦ÁFE1¼=®š"Üo< µµ"=õáñoÄ*ñ¡òý\‡VYU-KC{›kþµTœÃÂÂ"""¢©©iïÞ½±±±šššnnnÙÙÙHç&)PŒ·¤¤$ƒk×®?>//oÚ4Nëã=»Ôr…™ÆÂ‹)±¥õƒÒB|Ov¹ÌT“¬IL$T¿E.Û!ÖÕÕ$Ä›)ˆ>Ýã*'òáfÐÃò¦yç’)¯°áâB0 0&$$$vïÞýöíÛ¬¬,ƒ1kÖ,MMÍ   2lÁŒ+´¿¿?Ò&‹ÆÆÆ+Vøûû;;;ÇÅÅÍœ9“‹ßݹ¸¸\ •,x[t®œ(np!n z™‰Z{Ojæ3&(/Ç‘?þ·ƒa¸¥°ð]ÞSo3[p<ƒ Ï«Zúø×Ùz——Û P“úo‰ã)**zyy-_¾œ@ œ:uêâÅ‹ÚÚÚBB`k(`<€"`<Ðh´£Gzyy±X¬˜˜˜;vpø¹YZ²,Ú}§@˜Û\Uz ÅÅ5__QURðNúsÒûf94÷$]UÞßߘšÚU[sÑËúˆ«1zÈ'ý¥¬ Ÿ¨'» ™Mî2i›;wî¶mÛ„„„‚ƒƒ?þòåK%%%999¤£ s¹¹¹[¶l©ªªò÷÷ß¹sç¤ZLôRVůѹ›gNýg‰åÐϹ²w‹ƒ¿ë¡ÈÛÚŠL¾%Õº›šÞeeJócïl´7V’lgÁðž»gÒ^þía1t¿`R¡Ñh< |ö왕••¯¯ï¢E‹Ðh4ҹΊ€1D"‘þøã .XZZ^ºtIWWéDH|Ù¸4ôñLÍ)Qëì„ù¸ÛÉ4Æï1ùÁO*¤´µ§˜™£¹¹¿pŽÁ¤Ó[ Ÿµ•—¯¶Ô Zb)Èû¡"ì¥ÐW]Ëxøê]Ô:;·iÊÈeØ‹ÅJNN>sæÌãǧM›æçççîîJ`Ô"`¬¤¥¥mܸ±««ëôéÓ«W¯žÌ÷¿‹:^zÄϹëã¨'+6ô©Ä—k"²ILhй…(§O”ꪫŸ—˱þ]a3ìcþuk×¢Ë)„ŽÎ¨Nöþ÷yóB IDAT|—²²²€€€Û·o«¨¨ìÙ³ÇÛÛ›‡‡éPçEÀèëèèØ²eKLLÌÆOœ8Ö ¨½·IHZQ>t¥íÐ¥„ "’©;bòŸV‰(ÈËYXòŠˆ rìP»»›óóˆ ËLÕÏzZJ|´©ÒÝçukÂ3õeEÉ1Ç”äåîÝ»‡Bi;ÀGZ[[/_¾|æÌnnî­[·nß¾]LLìë/€¯GYDDÄÂ… [ZZnÞ¼¹sçN6ßþgÜàx°+Ì5:IÔÝw ½öÚr<˜ÿ:6ù°˜…FʪÒé¥okŠK4*NR…ánO&ÞZTÔ™!bF®½î4~î³ú¨ŒmÑ9{ï=[o­}s½ÃtCƒÉd3lH@@`Ö¬Y6l€ èܹs§OŸnkkÓ×ד€ŸzFMss³Obb↠Nž<) –ÆI\Yúˆ,a>îȵ³-þÖÀƒu>ó•Âs„’40’Ô›ŠBc>wöÇb2;**ñ¥%hóÀ|£ßìõy>®lŠð+Â2Ú{ûCWÚ.ž®2мyóæ7n,]º‰ÔÀ@"‘ÂÂÂÛÛÛ===÷ï߯­­t(`¢EÀè ñóó ™3gÒqؾ—²."+áeÃkSîfB¼ ì QŽ'—^Ȫ@ópKN×ÒBa&X)Àb2;«ª:KJèÔ~ýs§I }Ô!ÔK¡ïº“šS9WWñêê™R‚=ëããñäÉ“3fŒop`"!“ÉÿþûïéÓ§[ZZ¼¼¼öï߯©©‰t(`âEÀÏjllÜ´iSJJʶmÛŽ= zç¾ †CžTî½÷L Ç¼ÂÆQgøªÉ-ÝäãÉ¥ÁO*¹0XQm©©zX?"Q¿ ½¿_QA¬¨`Òi무þ˜;M^tøŽPoÞo¼žÝÖÓl¡É–™ºèOÖ¢Ó鎎Žõõõ………’’’|NŠŠ:qâDMMÍòåË<¨ªªŠt(`"EÀO‰ŽŽÞºu+‡»|ùò¼yóŽ3ÁÉÔ½÷ž…æTÚkËyZN2|e{oÿùŒò³½š°’’¸¶¶°¼<Ćó,`¸ç}sçë7Ýõõüܘ­3u¶ÛéM^µÔà{~»ý4áEãJsS‹Í‡u ÕÖÖfll¬¥¥õðáCÌDëÆ à |ñâÅâÅ‹=ª¥¥…t(`bEÀêééÙ¶m[ddäºuëþþûoÐðÖ7ý“_×Ñ»{ŽÁn'Ãúê7zz­“C¦1®Tç¼y^ßÎ' ¬¡.¦ªÆ'.ŽTà¡ú‰âÛÚîšjrO¯¢Ä&+mo žáëA‘iŒÓ©/N<,U8ía>__ñ«g.))±²²òññùûï¿Ç&;ÀiX,ÖÝ»w8P]]½xñâcÇŽihh  `w ø>\³f …ºv횣£#Òq&<‹u9«Ò?¾¸?ÿ¾¥šLì¿ç†.¤?¨ü=ñêÓ77 k[ºH‚¢"ʪÂÊŠ8 Éñî€!r¾»±‘T_ÛÓI”Æ-5VYc©e(?B]B¦1.gWœ|TFc°:Oß:K‹þÖé‘‘‘ÞÞÞaaak×®Õàd¥ÀüQ__¿téÒC‡­Š/EÀ÷¡R©{öì9w«khh(¸e;Š‚Î_ømû¯¼¶^BÆsv:êo²™*Â?Â2‚0 åÕ¶Ý*®¹WÚ𮳗ŸO@A'#‹“‘æËÔžR[k_KK_S¹Ý×NÿwGƒœ/óõõ ÉÎÎ611˜,ètúÍ›79ÒØØ¸fÍšpÌ~åÀèEÀwxùò¥——W}}ý… ¼½½‘ŽÃQÂÂÂ6lØÃpÈÕðZaí‹™,^g­åk§¯"!ø¹WU¶t%½jLzõ.¿®L¥óòóñIHòˆŠñЉò‰Šò ¡±?¸1“N§öôPÄ~"J$Rðø~2™k¦"5WW~ž¾Â°¥‡j"’Φ¿ É~Í‚aŸ™:{œŒ$y?wð—1 ''§7oÞÊÊÊþØI€I‹L&_ºt) €L&oß¾ÝÏÏL]†EÀ7aøìÙ³ûöí›6mÚõë×UTTNÄQ’““]]] A=rrrê£2¢žU¦¼¨nïž¡$±ÝNo©±:7æ³éLüê=!÷m[Q#¾°¡óM+‘Î`BÄËËË#$ˆÂáÐ<¼^ /ïˆû2it P˜*Ü×Géí¡ôS Â`PZÒbÆJb3%¬Ôd äÅ0Ÿ_ËÎdÅ–Ö‡<©Lý^N÷»£Á:k­OÇ|/`bb"##“‘‘Á=9vXF‰D:wîÜÉ“'±X¬¿¿ÿÆÁhS`(¾®¥¥eÍš5iiiÿûßÿþ÷¿ÿߟÑõèÑ#ggg&“9ð_±¸¸xúôéOQ̘âÚkO«2Þ¼—Áy[h,™¡f ÿõÕR,VU[w ¾§®£·¾³÷}¹­—‚ï£ú($ ÁdöÓGòb1X Z€+†ãÇñH ðʊ𫈠©HªJ jI‹|Ë-üò÷ÄÛÅ5yÕ „^[)«-´µ³³£Óé,k ¥¡¡AQqøàù†NRD~UTÁÛ7m]Ú2"3Tçé)š(K~:É~ܰ`¸¸¡#éUcLqmù{¢º”—©ú* MU‰1™'r÷î]ààà…càǼ{÷îèÑ£aaaÓ§O ´µµE:€0P|‹Åú믿üýý.\,ÎsÒ8IEE…¥¥%‰Db2™ƒ$ ‡¾ÀΠç7 ߯×6t’Dùyìµåtäl4dtdDÇá[ C¯[»rkZÓ*›Ó*›;û(ò¢8÷éªËLÕL•¥Æúê~~~ËÚØØŒõµÎV^^¾gÏž¤¤$ggç3gΨ««ý5‡EÀÈZZZ–-[VXXxéÒ%0p,ÔÕÕ™››‰D:>ØÈÍÍM¥R¿åå¯Þ’^6%¿jzZÛJc°Äp‘LÅ“úkð=5øž·í=Õíݽ:Ar"8#qK5éRcèN€ã‰H$šššJHHdff‚MåŸG£Ñ.]ºtôèQ4}øðá 6 Ñ²'ð@ð‹uäÈ‘cÇŽ-\¸0,, ¬8‚µµõÛ·o‡UikkWVVþÌɻȴWï ¯Þê:z ¤F©¾³·ƒD¡1Xßòr,%)È«$&¨(& (& "!¨++ª/'&ÊÏ.Ÿ¸¯_¿633[¸paxx8ÒYÑÕÕuüøñ   ©S§ž?ÞÒÒéDÀøEÀD"qÕªU>öù°ÿ‚¸¹¹={vÛ¶mHg8Gssó¾}û"##ÏŸ?¯¤¤„t"`\À Ã0\PP ¨¨8eÊ”¬¬,¤³p²/ °àâârwwG:àÄpàÀ “‘‘t€Ó<~üxêÔ©üüü‡¢P(HÇÆÜ·.cÎÙ‚‚‚lmm555ËÊÊÀœ™1®­­ Aа0 šôüýýçÎëîî^WW‡t€£ØÙÙ•––þõ×_ÿý·¾¾~rr2Ò‰€±5Ù‹*•êããóÛo¿mܸ111|5nnnooïÊÊÊ'OžXXXpqq ®‚‡B¡À<Ìo„B¡¢¢¢ddd-ZD&“‘Žp,ëëë[YYinn>oÞ<—úúz¤CceRx<ÞÁÁ!**êæÍ›gÏžk²Ž'kkk†gÏžíåå…Åbyxxèt:(¾  à½{÷êëëÁòAÀX““‹ˆˆHOO¯­­ÕÕÕõ÷÷§P(H‡Fßä-ŠŠŠŒŒŒðxüóçÏ—.]ŠtœI§¤¤$''gïÞ½W¯^mjjòóóEÀwÑÔÔŒŽŽ¾uëÖéÓ§‘Îp¦Ù³gýþûï&&&H'FÙ$pÿþý•+WšššÞ¹sGLìëkÑ£ÎÇÇ'33³²²rp…BéëëuÀ÷:vìØ¡C‡âããç΋t€cÕÔÔøøødddlß¾ýÏ?ÿäççG:0:&]O Ãþþþ‹/^½zuJJ ¨ÑÝÝåãã3t&///¨~Àþýû/^¼bÅŠ·oß"àXjjj©©©7oÞ¼~ýºººúýû÷‘NŒŽÉUô÷÷{yy;vìòåËçÏŸû"%""†áÕ«W#„pqq………ÉÉɹººöôô àd¯^½rppX´hÑ’%Kðx<Ò‰€Ÿ5‰Š€¶¶6{{û‡&$$lܸé8“ Ã/^\¶l™ˆˆÒY8„€€@\\_½zõä¼ÁŒ))©ˆˆˆ„„„¼¼<--­¤?e²%%%ÆÆÆ¡  `Μ9HÇ™Ô222^¿~½uëV¤ƒpeeå›7oÆÇÇ?~é,ç›?þ«W¯<<<|||æÏŸßÔÔ„t"àMŠ" ..ÎÖÖVCCãéÓ§šššHÇ™ìBBBLLLÀÎL£ÎÁÁáøñãHHH@: Àù„……ƒƒƒ333«««õôô‚‚‚X¬oÚ¡`+œ_\¹reñâÅ®®®III` âðxüýû÷7mÚ„tδk×.ooo//¯ŠŠ ¤³“‚­­maa¡§§çŽ;ÜÜÜÀ( ‡“‹€‰ëׯ߷oßõë×yyy‘N@W¯^Åáp^^^HáX—.]ÒÖÖ^´hQww7ÒY€IAXX8$$$%%¥¸¸ØÐÐ0%%éDÀwàØ"€B¡,Y²äøñãáááGŽ[²†CBB¼¼¼øøøÎ±xyyïܹC$½½½A÷,0n***æÌ™ãííÝ×ׇt"à›pfÐÕÕ5wîÜÔÔÔäää•+W"øOVVVMM ˜š1ÖïÝ»÷ðáÃÇ#˜D„„„"""nß¾`ll\RR‚t"àë8°Àãñööö©©©vvvHÇ> 555500@:ç³²² ¨ØMTTØ«igOýýý7nÜs5´jÕ*Ÿµk×#˜¤455óòòììì~ùå—€€“>qMìÙiii ,X¼xñÕ«WÑh4Òq€‘ݺukåÊ•MMMÒÒÒHg™¼ètº££c}}}aa¡¤¤$Òq€É+$$dÛ¶móæÍ F:Îd7‹€ÔÔÔ xxx\¹rTìlîܹ &>>é “][[›‰‰‰††Æ£G0 Òq€É+''gÉ’%‚‚‚÷îÝÓÕÕE:Τ6Qodgg»¹¹¹ºº†…… €555¥¤¤¬Zµ é $--ýàÁƒüüü]»v!˜Ô¬­­ËÊÊäååÍÍÍÁzVÈšE@AA³³ó¼yó¢¢¢À6%&&æêêŠt‚ hÚ´iÁÁÁAAAaaaãy]..®±Þ¿c.Œ"IIɤ¤¤+Vxzz:t,,ˆ”‰w;àÙ³gŽŽŽsçΊŠ}l†ammm''§sçÎ!ø`ÇŽ—/_ÎÊÊ255Ÿ+|<é»Í8\ ááá›7ovttŒŠŠ눌¿ VÛÛÛÛØØÜ»w‹Å"øŠÂÂBSSÓüü|333¤³0™Lggç²²²¢¢¢ñYÏÀ¼|ùÒÅÅ…››;!!ASSé8“ËDºP]]íâ⢧§ *€ !22RWWTìFGEEñóó{xxP©T¤ã“¾¾~~~¾¨¨¨¥¥eff&Òq&— S ì $++›˜˜ˆÃáŽ|ƒÁˆŽŽöôôD:011±{÷î•••ýöÛo_>rÄ{íÃ’ÉäM›6IHH º¹¹Õ××îœ4- ÀÈȈŸŸŸŸŸßÈÈèÔ©St:}ð€œœœ•+WÊËËc±Xqqq''§”””¡g¨««[¸p¡€€€„„ÄæÍ›Édò·ÿì’‘‘yüø±¥¥å¼yónß¾tœÉžZ[[ÕÕÕŒŒºººÎ|«‡rqq½}ûé Àgݽ{—‹‹+88ø ÇŒøF1¬qàá¢E‹†¾·ÈËËwvv~z<…B±µµýô½höìÙ4mèñCqqqÅÆÆ<;°#åÐg/=*-R ÆŽ;¸¸¸Nœ8t–ÉbüΉDeeåææf¤³ßaÕªUæææH§¾ÂÏÏ‹Åfee}î€o/”””233{{{322!Ú³gϧǟ8q‚ ‘+W®´·····‡…… ,ø}òäÉcæÎ›œœÜÕÕE£ÑÞ½{wæÌ‚LLLžÝ³gψ—Eg¸zõ*‹]µjÕ`QŒvÿéïïŸ5k–´´tuu5ÒY€ï@&“ƒ‚‚|“Éœ?¾´´tSSÓˆ|{7Ørÿþ}‚ttt>=ÞÀÀ‚ «W¯=á¿ÿþ A‘‘ÑÀô´4™¡s€yyyžÕÖÖñr à)))‚‚‚ÝÝÝHgáplý;Ãd2—.]ÊÏÏŸ››‹tàûܾ}ƒÁ´µµ!ø: ¡¡1}út2™üé³ß^‰Ä¡çú±=ôx^^^‚ðxüÐl.ÇÇÇÃpttôçfüÌÃÃ3âå@ÀIrrrÄÄÄÌÌÌÚÛÛ‘ÎÂÉØz`àüqçΘ˜KKK¤³ßçæÍ›öööRRRH¾NTT4..®¦¦fÓ¦MŸ>ûéÔ»þþþ1ÍsäȆ}||Þ¼yÓßßÃ0‰DÓ+lÈÊÊ*77·­­ÍÖÖ¶©© é8‹}‹€ .DFFΛ7é,À÷éêêJJJZ¶lÒA€o¥­­õé²NÛ> êÿäÉ“O2´=++ ‚ •O˜ž””4´1!!‚ ---‚jjj :qΩ¦æ@·ÁãLJyòä°§¼½½‡žLœlH$’£££€€@jj*ÒY8 ÛýÎttt¨©©ÙÚÚR(¤³?‚@ `±ØÈÈH¤ƒ?¢§§GWW×Ðа¯¯o°ñÊ•+ÚÚÚX,VAAáðáà cÄ"€D"­[·NTT‡Ã-X° ¶¶v؃)ʉ' xyyùøø *† Æ©S§444xxxTUU><¸ŽÐàjkk]]]q8œ˜˜Ø† úúú@ÀÙH$’“““€€À¦³?€½ö`0sæÌijjÊÏÏC:ð#"""6mÚÔÞÞ.((ˆtàGTWW›ššÚÛÛÇÄÄ|ã¾|`Ý~`P©TôôôøøøÙ³g#‡C°×ÀÀ_ýõùó牉‰ ˜¸bbb@0qihhܺu+66600é,ðÏýû÷/^üË/¿ÄÅÅ!‡C°Qzûöm ¤³?¨»»;55ÕÝÝé ÀOqrr:räÈÞ½{“““‘ΠÑè+W®xyyyxxÄÆÆ"‡°Ë퀬¬,GGÇ÷¤³?îúõëëÖ­kkkì L\0 /[¶,%%åÙ³gÃõ¿ÜÆ“É\³fMLLL||¼ƒƒÒq&6¶(ZZZŒMMMïÝ»÷÷ ö´`Áƒ‘˜˜ˆt`ô÷÷[[[÷÷÷ççç¬íl‚Åby{{ÇÆÆ>zôÈÊÊ é8ò· ÆÒ¥K………#""@0¡‘H¤ÔÔÔaóÄ€‰‹ïÞ½{x<~ÕªUìðm¡P¨ððp''§œœ¤ãL`È»ví*--}ðàJ6Ñ¥¦¦R©TWWW¤ƒ£FII):::!!áØ±cHg€ Ñ興ˆÙ³g;;;?þé8ÂE@TTTPPPhh( Èbcc­¬¬À~ÆÞÞ> àСC+ûûÀb±ÑÑÑ:::®®®uuuHÇ™PYYijjºzõêO—+&&“)--íçç·{÷n¤³£oíÚµwîÜÉËËÓÕÕE: |„H$Μ9“J¥æääHJJ"g‚A¬ P({>}út``BËÉɱ±±yýúõÀ0‡¡P(¶¶¶ÝÝÝ`êÀnðx¼ 77wvv6øÿù]»°oß¾ššš˜˜Pp†øøxMMMPp*^^Þ»wïvuu-]º”Éd">"))™””ÔÑÑáææF¥R‘Ž3‘ SÄÇÇ]¹rEMM ‘À¨‹C9›‚‚½{÷222üýý‘ÎéªªÆÆÆmÚ´ Lfùv­­­ëÖ­[¹råâÅ‹ÇÿêÀX¨®®®¬¬tqqA:0¶¬¬¬þþûïcǎݾ}é,0œ©©é;wnܸqäȤ³L˜q¾ ÃkÖ¬¹páÂ8_; `ÉŽÉ`ëÖ­eeeëÖ­ÓÑÑÑ××G:|dΜ9‘‘‘Ë–-“““[¿~=Òq&€ñ.®\¹’’’’žž. 0ΗÆÎÇÑh4ÒA€ñpá…ׯ_»ººJHH >âééùòåË­[·jhhÌœ9é8ìn\g444èëëoݺõøñããvQ`¬‘H$qqñ°°°+V '­­­ÆÆÆ:::ÉÉÉÌx—€/ƒaxùòå©©©ùùù`äÙ—_ð]OOOAAx×à$IIIÎÎÎ---ÒÒÒHgÆO~~þ¬Y³¶oß~òäI¤³Àp$ÉÆÆ…Båääðññ!‡}ßÀÀK—.åææ^¹rT&%%ÅÐÐT“¹¹yHHH``àÍ›7‘Îà ÄÅÅ555mÚ´ é,lmœŠ€ššš={öìÞ½ÛÐÐp|®Œ›””'''¤SðööÞ¼yóÚµk‹ŠŠÎÃ)((-((8¦ñòåËŽŽ¤ƒÈ[¾|ùÎ;·mÛVPP€tNCCãŸþ HMME: {ÃÛt:}úôéŠŠŠ‰‰‰ct YÿüóÏŸþ‰Ç㹸¸Î Éd:;;—••ÊÉÉ!†[¹rejjjii©ŒŒ ÒYØÅö\¾|¹ººúôéÓcw YOž<±²²0FGEEñóó{xx€í\6tîÜ9>>¾Í›7#„ŒU@ :´sçNmmí1º€,†³³³Á¼`(11±{÷î½xñÂÇÇé,0œˆˆÈ7®\¹‚tv1VEÀÁƒÀ( VYYÙÑÑakk‹t€½DFF†‡‡_¾|é,0œ……Åü±}ûöêêj¤³°…1P^^nhhøï¿ÿ®^½zÔO°‰Ë—/ïÙ³‡@ €u Oíß¿?00055lã°ƒaaaÁÍÍ f ŽIàââÒÚÚZPP€BßÞÀ8[¾|9OIIA:ÀŽX,Ö‚ ‹ŠŠäå呎©¨¨˜1cÆÑ£GwíÚ…t„þ‡tjjjBBB`` ¨8[VV| …ºqㆸ¸¸««+™LF:|dêÔ©{÷î=tèPUUÒY6Ê=0 ›™™III%$$Œâiv3°e@zzúìÙ³‘ΰ¯7oÞ˜™™¹¸¸DFF"å#0 5zkð=š}2…ØG#’©D2•Éá]Qˆ+ÊÏ3ðGZˆOMRhດÜ›xètº©©©ˆˆHzzúdžâ4ÊÿwïܹSRRR^^>º§ØM^^ƒ133C:ÀÖ´´´"""ÜÜÜŒ}}}LBg²Jš:òkÛ_6^¼#T´IT:A8Œº¤°²¸ ¬0NwŠ˜(Ž[ŒŸƒá#¡»ŸF$S }T"™ú²™p¿¤¾µ‡ AÅ¥*!d /¦++j¢$e©&-†›¤LX,6<<ÜØØ888x2OfÍžƒ¡««kff1ZçØÓ®]»ÒÒÒJKK‘L‡þóÏ?SRRƹ߈ɂ ëñI¯³«[ ëñdCˆ—Û@^LOVÌPAlêQMia!þ>•ñß]ÙÒõ¢¹óU3ñEsgC'‰‹ Ò‘µR—vš*ï¨#/ÌÇ=Š?0êvíÚZQQ1i—·Í" 22rݺu•••jjj£uN€=ÙÚÚjkk‡„„ ˜`öôô|üøqaa¡ªªê@#ƒÁؽ{÷úõëuuuG÷r}TFâËÆeõÊßuöQd„øgiM±R“±V—Ñ—C£Æ°ã÷}9çmknMkvuKÙ»N4ÊJ]z¾¾¢ûtU °t:;"“ÉzzzÓ§O¿sçÒY1jEFÓÒÒrpp •l‹Á` ­_¿é,ÀÄ@"‘,,,Ðhtnn.‡ëììtwwÏÌÌÜ¿ÿ±cÇFå:óAY}Lqmò«&ƒ5SsÊ]y§©òrâˆÜðmëéO«lN©x—ø²±³b¬$é>CÅËT]AT4ÀçÅÆÆº¹¹%''ÿòË/HgAÀ¨!!!Û·o¯ªªRTT•l«¬¬ÌÈȨ¬¬ÌÀÀé,À„Q]]mjjjggwèСùóç·¶¶2 YYÙwïÞýä°¬ò÷Äs^GäWu÷ÓfjNY2Cmñt Þoy-Éj$ê:zÛ{û;û(„>*¡J¡3ûhtƒ5pŒ?7Š‹KÇ+†ãÃñˆãx•Ĕſ±«ŸÁb=®|»¸&¶´¾»Ÿö‹®ÂzkmgE ˜?Å6\]]«ªª^¼xÁÍ=énߌN@¥R544,XpîܹŸ?ÀæBCCwîÜÙÕÕÖپ˃-Z„B¡`f2™™™™?¶  CË›N¥”e¼y//Š[g¥½ÞZ[^÷å—Tµw•4v–6u>oê|ÕBlëîc±`‚¸P\¼¼¼X^7/æÓÿØ0‹BeP)T •Ag 4 ñó¨I ›(Š)ˆÊ‹OSÿò4*ƒy÷y]È“ÊìêYaœ¯½Þ&[!ÞI÷©Ã†utt<èçç‡t–ñ6:EÀÙ³g÷íÛ÷öíÛ)S¦üüÙ6·qãÆ7oÞdee!˜H Æ–-[†Ý.äææöööþÞ{ˆL|³ðí©”²ï³4esÐsÖWúÜÍ~‹UXÏ|Ó’]Óú´¦½‡LA£Ñ¢¢Q^Qn!!AAAA ß7^ÅdP{zi=½TRµ«›ÖE¤”~ Ò——˜¥.m£!3[KV”ÿ³s^·vÏ(¿–÷ƒBmž9u‡ƒ¾”à·^#êçµIåM+ß“(4œ ¯´ NFF@FšWDtÔç…ÓûÉ}mí¤–V ¾µ·­â‚§)JÎ*ï1CÕ@^lÄ—töQ.gUžËxÕGeüj§»ËÑÌ-DP¿ŽŽÎ¬Y³®]»†t–q5 E@@@À±cÇjkk%$Fþm8I__Ÿ°°ð7–,Y‚t`b¨®®ž7o^}}=ƒÁñ€¸¸8—¯žçQù»=÷òËßW˜iüoÞtu)¡O¡Ð™qe ‘Õ+šXLHHVF@AQXI‘WXägŒoƤÒzÞ5u76’Þ5Qû)ÚSÄV™«/7yH`?q9«2àQ)…ÎÜíd¸ÓQ,=„”ÈÈÈÕ«WM›6 é,ãçg‹€žžUUUŸ?ÿüs´2ììÉ“'¶¶¶uuuÊÊÊHg&†ÜÜÜ5kÖÔÔÔ°X¬OŸÅb±nnn·nÝúÂ^·vý“Ÿ\Þèi¬vØÅXSZøÓcž7v„徉,xÛOgÉÉ )«++a¾­ƒaŒÀ0Lji骫#5Ô÷÷‘ítä6Zi/0Râùd̙Ƹ˜Yq,ù¹0wÀ"³%3Ô&ñvˆXñVBB")) é,ãçg‹€'N?~¼¦¦tL§OŸ>uêTkk+ÒA€‰„Á`\¸paß¾}t:ýÓþnnî¶¶6‘¾¬÷Q‡â‹Î¦¿Ò—;»ÔÒJMfØ,¾WRwâÑ‹âúv! qa-mqu 4›¶ƒážwÍ„ª×]õõB|ܾ³u·ÎÒýtþ¾—ò¿…ÿæ¼¶T“¾¼ÜFWV‘°“ÙÀ—œ´´4{{{¤³Œ“Ÿ*úûû•••ׯ_?Z3}ö·téÒ¾¾¾øøx¤ƒÏû÷ïwïÞ}ãÆ  5´W…Býûï¿kÖ¬v|Ò«Æ­7r»ûi‹ÌÖYk¡>þvLc°®>}sìaÙ;b¯˜ŠŠ¤NRj<~ŒŸÀ Pð•„Wå0ƒ¾ÎJkï/†ŸÞ#(iêð¹žSú®c·“áÿæMçÅ‚98ãjΜ9D"±  `’l(ðSE@ppðo¿ýÖÐÐ %Åî¿{ÀhQUU]½zõÁƒ‘LT ›6mjkk$ˆF£­­­333éî§m»™{½ zñt•sK­¦´¸/ƒÅ Ï«òO(ié&‹kiIð0>€m±˜ŒÎ×U/Ëhd²ÎÞ_ŒdE>ú™,ølú«q…r"¸Èµ³M•Áìø)..611¹ÿþ‚ Î2~¼`2™šššvvv`‰ÀÉ£³³SRR211qîܹHg&02™ð×_A4pw€‹‹«©©i`ýö§5m+®¤“¨ôËËmMSöÚ¸²†wò:Iâ:ÚÒ†Fܸ/- ÀÎ`«óMUGY ƒÜ¿ÛÉ`ï/F8ž†Öwö® ÏÊyÛzÄÕxÏCÔäøbÊÜÜÜêëëŸ?>:~¼¸w‡GEE…––ÖèfØVZZš££c[[èû~^aaáºuëÊËËY, …úûï¿·o÷ý+¹Ä?¾ØAGîêê™Ãv÷yÙLØ~+/«ªY\CSÖÄ;a?þ‡‚Y¬ŽÊʶâb!Tà"Ó•fšC?wX0|*¥ì`\‘µºÌuöÒB`9ñðòåKCCÃØØXWWW¤³Œ¹/LMMeeecccG7ÀÎN:õÏ?ÿ477#àL&óüùóû÷ï'“ɆFÊO<,o:¹È|»ÞÐÏBƒu,ùù_É¥8q‰)––8Ž«ATjkq¾¢ÒFC抷­ªÄGw7ž7v, }L¦1îlr4Wå´Ÿ=-^¼¸¶¶v2tü`00„2''ÇÊÊjÔ3lkÅŠaRÍŸÆAss³÷º é’¥7Þß»ÂBUzè³…õø•ײj;{§˜˜JN qî›2¹³ã]V6½§ëÄBÓ_ít‡öÿw÷Ó¼¯f<,o:ëiµÉVÁ“Daa¡©©éÇçÌ™ƒt–±õƒE€««kgggnnî¨Ø™¾¾¾³³óñãÇ‘p”GåïäVPR[°`rV¡Ðh++;ûÜ7Vqïˆ}ƒO™(K>õ[@¢ÒgŽÚŒº;vÜ¿¿®®é c軋€ÐÐP·zõê1°µ²²2]]]4¬_ü, oˆÌyR½Á~•…æ`{?±88õÄÃ2yK+¥Y³Pèɾ•Ž¨ššæ‚…•DÊŒã÷K›:ÛU$³w¹¢¸¸lãê:zLÈÙ–,Y"##séÒ%¤ƒŒ¡ï+ètúÅ‹7lØÀÏÏÿõ£ÎRVVfhhˆt `ƒahËœ¨gÕ÷7;¹OWloëé·<ÿ¨ªMÓÅUJWÁ„l…OLLÓm1CDÂâäƒø ƒí²"üY»\DùyìÏ$4wþ€1Åb7lØÚ×DZÃßWÄÆÆ¶··oÞ¼yŒÒì À¨ø5:7<¯*~ë/óôßû¬ã«{¨j..8i0þ#(,VÙÁIPUÍírjtaÍ`»„oúNg1ϬÓñ-Ýdr°Í›7S(”¨¨(¤ƒŒ•ï+.^¼èì쬨¨øõCÎòîÝ;Šà'K*¹œ]¾z¶ƒŽÜ`cmGÅ©¸vFÝu!¯ð$ðe\h”¢íL)C£åWÒÃr_¶ óq'lû… âr¹ð°—BG0!§’’’rssãàÕñ¿£xýúuVVÖ¦M›Æ. À¶ÊÊʸ¸¸ L`áyUâ CVØ.1þpàM[—ÅÉø Ÿê¼ù^0çíKd§Ì0Ù™}6ýÕ`£ŒÚŽù-Ýä%!iŒ!{3£ÅÇǧ¨¨¨¤¤é câ;Š€+W®(++süòIÀˆÊÊÊ”””„……‘LTÊê×Edq5^kõa·‘·í=¶§¨|ªóæ¡yxŒ7QÈL3’33ÿíöÓ‹™ƒŠb©¿Íϯk[y%ã'ö…Ffkk«­­}õêU¤ƒŒ‰o-ètzxxøºuëP¨ïžPp0 ø•-]«®fz«ý1wúÐFó€Tœê¼ùh,7‚ñ&iy ËmÑ9ç3ʧN\cS\ð¨ÁlœjÕªUÿÇÞ}‡5uµ?Y$„0ÃÞ2eÈŠˆ8p‹ ëªÖÖ:jkmµUë¶U몫ֽZµ¶nÅbEEÙˆ ²—ì„ û~\¿C€$7 ç÷|Ï÷4'çÞûÞpMÞ{î.\àp8X"{Òþ¢ß»w¯®®Ž ì³233 €uJjds§îoªwú³¡¢éEjšØcÝçR4mÃFá‰}}(`w»»›zyûïók©mCØ'xXïž6pýÍĨ×eƦ–æÏŸßÔÔtëÖ-¬‘=i“€³gÏŽ1]íêk¸\nnn®»»;Ö@ªG D"ŽÆ°8¼›KG“‰ï'™`óGUs„ýÆŒ#’a?€ž0÷÷§;9Ï>õ(±¨FTøýÈó9O?þ »¢ÃØÔ©©iXXعsç°Dö¤JÐ…ãæÍ›'ïh 唟ŸÏãñàlÁPìɈ}ûî‚ᢠnÌ;›ZÆì7f Î8Ò ÖC‚)&¦ãE•0X¢Âƒ3ƒì u>=ý—; ÊÒœ9s¢¢¢˜L&ÖȘTIÀ•+WH$\.¨ÏÊÎÎ&ÎÎÎ]W… 1)%µëo&näâh&*Üv5¹ÐväHM} cS8<¾_ØH6‰~$º•ÇG ©Ä+‹ÃÞV5¬¿™ˆmxjfòäÉ$éÚµkX"cR%.\˜2e œ%°Ïzóæ ß‚º£‰Í›~,fdËGµu)½óªä§ë‰Au,-1ŒMmHýF}SÚÿçcQ¡ƒ±ÎÑ9Cöi48'Ð!ÂÇnÉ…§l.†±©™éÓ§ÿ÷ßuuu]WU]'ÿþû¯¾¾þ¨Q£ ¤œÞ¼yãââ‚u*‰/¨þ#öõA–úZh‰A朎åS(ÖC†b›úѵ¶6õòúîR¼xÀ£s†pùŸ®¿Ä0053aÂ"‘xãÆ ¬‘¥®“€+W®„‡‡“H$D)!AÞ¼y[ é±y‚ÏÎ>šèaói`ÛÂÓÛ量(¨¶†'Á²gîç§id<ùèQç-òáÙÁGgý÷æ¶±© 6bÄ5(ØEPZZšðÉ'Ÿ(&H •••±X,˜@ÒÛ“Q^ᬒ QÉ«rÆ–;)&¾¾šúú¦Îp8Ë!!…u¬_ʦùôãfµüßçp:aY ðàAK‹ú,×ÔEpëÖ-6lØ0ÅD)¡ììl|I©¼¾yû½Ôã}méÚh‰@ˆÌÿó‰ÝÈ®=!Od]³ÀÀ]Qi¥m­ÿ˜œWÓ >Ç0ÔcÇŽe³Ù?Šè" ¸yóæèÑ£ÉpNï>ìÍ›7FFFt:ë@ ÕðÕxK=Ú÷#Ûæ—Üó =£¼Î24ˆºBòaäâªmn:ûô#žàý­?Cí5c¼6ÜLªlTŸ›W YZZ0àîÝ»X"3’’&“;iÒ$…E)!84’ÞË¢ê“òwN Þ·”2Y›o§ ð ÀÕ§Ì ~[U/¾¬ÀažÚÒÖ;깞â;öÎ;XG!3’’€‡ …Â1cÆ(,H Á¡ôÖ\{êd>ÉÓVT²êêK(O€#ÇÌÏGHÒøéFÛàÀ¹û›êm¸™„aTjcðàÁT*õÑ£GX"’’€„……),H 1Œªª*Øu AÀú›‰ãXûÚ´Ý6üxõ¥¾¥…® †õAxÑØ×ÿ̳·¢ið8Üúq>ÿ&å§—©ÕD7˜ÐÐÐ R›¾MÞ¾}[RRçêãÐ&/'''¬”݃ì²äâÚõã|D%7Ó‹‹ªÍaUŸEwt¤®½Ñ¶|@„o¿þ¦z»£Ó1ŒJm„„„¨ðßÿéèèøûû+2HÙäååihhØÀ;9¨+;£ÒÂ\,û£/…²æzÝÞN €#_ߛ酢…†ñ8ÜOc½þIÌ/¨…=z+$$¤¼¼¼¨¨ë@dà£IÀãÇCBBàD}\~~¾ @À:H©¥–Öþ÷æÝʰ¶i"3Šs*™ÆÞ>¶‚äJ×ÒJÇÈxÛ½4QÉ ?{ =­ßÿ{-a+H¤P(Ož<Á:øhðäÉ“!C†(2H ØÛÛc¤ì~ÿ﵋™Þ(×¶…·ßO×·µ…ÍXÂCoï[éEo«Ð¿4Ôõô³œ&6ÛÐT™Löññyþü9ÖÈ@çI@aaá»wï¬àh e“ŸŸ“H²úî¿Iùˆ¹‹¦zš[ù² ÊÄË Ó¸  gmCÓ×ÛÕÖ°0Ø…'^LÌÃ0*õ0hРÄÄÄ®ë)½Î“€¸¸8 …âçç§àh e“ŸŸogg‡uRûóÅ["?w`ÛZAû¾Ò51¦a8 ïæv!!¯º©-0Ð"âg÷G,|"Ð[>>>™™™ë@z«ó$ !!ÁËË ÎÜÇ577WVV–HÇžfÍ𷣑ß÷ªhh¹•^làêŽm`Šî舄?_¼•,Ò?£Œ‘\\‹aTjÀÇLJËåfffbHouž$%%ÁqPaa!‚ 0 €$H-­Í®¨ÿ<ÈYTrêÙEC6 )<‘¨gït(6AÞ—Ù™:™èžOP“ ï°âä䤭­’’ÒuUåÖIÀçó322¼½á4Ÿ}]~~>‡ƒ þIÌw4Ödg‚¾"ȱ¸]{G¡‹ÅÉ …1té_R×ø8÷ú‡sÿIÌÉBàñx//¯ÔT•_‘¡“¨oÞ¼imm…I”ŸŸojjJ¥R±RR.'|â×–&¾(¨*«k¢ÃÙ¥”‰¦Ž!ýÂ˶΀3ýí+[âò*1ŒJ xyy¥§«üäK$ééép¦X¨  6@¤”ÔÕ5Eø´]$¿ÌÓ¦hÂ…§•ŒŽ½ã¿I¾}éd¢ëaip-µÛ¨T««kVVÖQôV'IÀëׯœœ`¯@Ž„$‹Ì(îg¨íeõþ'Ÿ/^L*жƒ×ŒÒÑw°c±yÑYe¢’©Þý"3Š1 I 899Õ××WWWcH¯tþ8®˜@]¹ýªxükÑËgyUL[ß®†!AÒТé_»õçn]XÛ”UÁÄ0*Uçìì ÈÉÉÁ:^é$ xûö-znP_&ŠŠŠ`}LUckJIí7+QÉW%Úúz]= £‚>†fcs+£DøÿA¾6†ÆÚš÷2K±J¥™››Óh4uKA^^\5*--åñx0 €>æá›r?ÔÉLTrëU)ÕÒJÂ&†t­¬˜,vjÉû¥„ñ8Üðþæ²Ë$oI€ÃáÕ- (//çp8˜D)t,[[[Œã€”Õ“Ü cÑAïê[ÞV2´--%oaEÓ€®I¥Šÿês6Ë«ä …F¥êóó󱎢WÚ'ÅÅŸt,T\\L¡PLLL°RRÏó«;´]Or+p8¼¶™™„M ,áÕÜü¿œ QÁ`{Óf?£ŒaPªÎÚÚº´Tµ©´OÊÊÊH$’©©)&Ñ@Ê£¤¤ÄÊÊ 'Z‚ÄÔ·p_¿cŠæÄåUjâ‰D £‚$Ó23}ž_%š#ÈÕLß@‹ü,ÎÐsåååXGÑ+í“€ÒÒR333¸~&­´ÎL—jªó~6É.ÿÍ;¦–±±ä­ lQôõ544 ÛÆµûX¦•Öa’ª³°° …••*ÜšÒ> ¨©©1†ÿ’¡ÿ?À: HIe”1<, D/_•3B!ÕÈà.áp8-Cƒô²¶_ýo*ëE3 BÝ…Þ3—•©ð ‹öI“É400è´*Ô§”––Â$ú˜Œò:‹¶¹3Êdm C‚¤AÔ§'‹Ýú{XÐùBavE=†!©4SSSWQQÑuUeÕ> `0úúú˜„)ƒÁb±àã¨Sr*\ÌÚ&zUΠêëØ‹Téiêëg½cŠ–v2Ñ%âñ9U0 è!‰¤££Ã`¨ð‹NZ`•””`uª²±¥•Ç·3l»ïÏ®ª'èÁ‰UE_ÅæV5µ /I¼¥¾VAM¶V, IDATQ©4===&S…g_nŸ455éèÀ6½¾&EuM[º¶¨$¿¶‰LÓþø² Ót…µm¿úý µ‹0 è9==½úznJiŸ°Ùl …‚I('y`zï+(€übPØ©•––Òét*•ª˜Ã)9xQµSTׄÞA¢/”1XÚêœ$ûá’ýÔái‰¦…ÇãÅ“[º¶øK¨»Ô- àp8˜„¢róÛ0{öì½{÷òù|Q ŸÏß»wïœ9säwP8IVT⢪hh1ÑÑ$àßÇYÝÔÊã 4´ir‰’)G¥i•0X¢s=jEC †!©:}}}µzÀápÈd2&¡¨ AQÇ›^›;wîÙ³g}}}Ÿ?xöì™ÏÙ³g?ýôSY¢#8I€²Qª‹ª–Å6¤µµV7µHun7òMB|“döùc‹HÕDÿd(#šf-‹a<ªNWW·¡¡ë(zîƒ$@ …B‰„U4PGcÇŽMKKûî»ïfΜ ˜5kÖ÷ߟ––6vìXù&ê­—U‹#žÔ5³Dì#BÝ‚#SêXÑK:Œþ¡žÑÔÔd³Uøü Àãñ¡Œ•Š‹‹›;w®¥¥%‰D¢Óé£FŠŽŽ¯PXX8yòdfhhøÕW_µ´´o’ê²B—¸\îÎ;½¼¼¨T*•JõòòÚ½{·ø|>ÿÀ~~~4J¥†††FFFJ¿¨Í'F¼DúÐú`ëÖ­¶¶¶d2ÙÅÅåÌ™3â'‚ÇãÑ}âp8ôÏ$WÝš)¿µµuÙ²e&&&D±ÙãÏŸ?ª§§G&“V­Z%ž2£²X¬Ï?ÿ\WW×ÌÌìÀƒñé§Ÿêëë®[·NüXò‡éåå…Ãá.]º$Þ¥K—p8œ———”Qu ^TuÍlºVÛO~-‹Ãá,[¿æòá7ŸJ3N¨‘1Ƽ`UDãËô]VZ\áÆ¹ã,SIéÃé¹_jŒoûسf{%ûá˜>¸l˜.%ûá²f¿¿lÚõ @_"BAÅ©­¯&Ú¦ "¿Žp©»õÁÇË)ËÏ[ž:„–>°dû!»EI:àÉ”±[º…˲8*<ñ-¶H$—ËÅ:Š^@>D þþûoD: ‡Ãݸq}·¶¶¶ÝüÄS§N©Ë Šþ7›Í éưaø\.‚ \.wÔ¨QûL$Ç/áÃìV ¢ú_|ñE»:—.]B$**ÊÓÓÓÃÃ#..7`ÀOOϨ¨(™ü™:D"QúËvÚ´i⟃P(œ={vÇwsskhhßpÊ”)ânÞ¼ ^ò×_¡õ»ü0÷îÝ ˜8q¢xx&LìÛ·Oʨ>v‚RÆÐ.ªÑî|ù×cÑËSqo4¾9ƒ6˜cõ?ÃðögŠúh3>gÿÛ ô]Ë{º!Åw¨;dÀjÅ>ñ=ˆÞE_v<¨ÝŽKhϘ’á *ê ŸÚn'XýÏø÷g;oŠþ|qy`ѱwõÍÒü顎V®\ˆu=×>ý'l¦;vì½{÷êëë¹\nYYú-¼mÛ6ôÝ]»v•••ÙØØÄÆÆ655=zô())I|ó.+tiÿþýOž<ÑÓÓ;}útuuuuuõ©S§ttt=z´ÿ~ÀÁƒ£££i4ÚJKKÙlöóçÏ'Ož,Müȇß˨Ä òàÁƒÈÈȆ††’’’ððp4<À™3gæÎ›œœñ\ÏÿêöEê |Ÿéu€ •§Þìô1spbãóûü†÷— ¿¾¶ñEŽH2+©§dc‡}‘^Ü)Ñ Tÿs}«òÏ¼Ú s[§ã±ÞOšœŽÇ¶d'ËéÜ» '°ym_òd"gî1uk  R©gΜ‘I~3qâDSSSñöa …‚¾Û¿À­[·Dõ¯_¿.R—:%^ÁÃÃÐîtNž< ðòòBÄÓÓpüøñÄtö}݃Dõ£££E ÚÚÚ÷,áÜe%55““#e}4þk×®‰žZô°_'hL¿Í Œ™Ñÿ¬›:œ¦Ûö±N˜ßð$²îÞy£éKu÷ÎèçK>(Í»íã%›Ù-ï?^NE€æÜVY쿱…#àÙb÷ýdÀáɦ+X¤ê-íÿéjkkwüšèŸþA%K–äää´¶¶"Âb±ºÞLi(>~ñ9š°š¦¢¢‚F£iwsî—v³M£?-r" E?6íÖÞ Iu»’nýJM˜0N§¿xñ¢   ???>>žN§?¾»QɃÚ\TPºÁr4 ÷ë¹Î§ŸY~»KDžJk|~¿tÏrÀ»“?1š¶ÄíZŽ÷óVß$Äûiû]wÈ¢.½9ã§¼€S–ßü*ž¨K× /ù x ±XO'Õ-8¸ÌƒìÈð:&Ú':::2IÐ&Ö;v899¡ßD>¯Ð¯_?ÀÓ§OE%?îV….999îÞ½+^xûöm€³³³èÿoÞ¼ÙƒøÁÿ¿UÅg\éA J¨²²RtSÞcnnn€—/_vÚÕ³}JóajhhÌš5 pþüy´`öìÙ¢ù¯z¼¨d"ËŠ¿ ±ÿĈ4 “y?Úí¼ìz1€¶ pÊòËvP¬ÐŸíÆÄ;IÃ`ô,ãîyÆÝóƒ1³q¤žO›†6 °ÒâD%¬ôg=Þ›l!|!Y¬!m@Û >H^-è³]»v1ŒúúúË—//Z´H¼Úz¹lٲdzX¬ØØØåË—w«B—Ð~àß}÷Ý_ýU[[[[[{öìÙ+VˆÞš;w.`ÅŠüñGyy9‡Ã‰G;«w?ÀÈÈpùòe ͹]Æ „***zŸ ­ñááá'Ož,**jmmåp8oß¾=qâDPPPÏö)凉6þ_¸páÂ… @ìY€L¢‚@“±[ "^(À¸19gaãîynu"àó™5̇WÀÿü5L¬•íâ72Mõ̘Ë%[ÛìàÿÿŒ{êî_R< \Pºû[VêSak3+õiéîo{³CB„´3 í(^õ)¸v7@&L000øë¯¿z¹ßÝ»w¯ZµJ¼dÞ¼yènÑ#ÖÕÕyyy•••‰*L:õÚµkÒWèü|Ä9NXX˜x[*444**JCCƒÇã;¶ãÝ‚ ]ÆøüóÏÏž=ÛnÃîÆ>Òè݃–pY‰ˆˆÀãñíFÛKð±P¿ýöÛßÿ½ÓM:~PÛUw?LÔ€233ÑÿÈÈÈèVT’O^T€1ïZéÓNÌ}?Lñô³œ¯þy1@,ÙR¼NÇßN]d³öXÕ_»Ë~ð±ÓÇÏ«»óÀ÷ÃуY3´æg4¸þóÁeƒî_T¿ÝËŽ…|FuÖ,O^]¥è]½¡“êßĈ> È/}þ¼_kmüªpôå³üÊà]·ÞíúÔLWç|”Ÿ_ýõÔ©SyyyXÒCí[LMM+++;­Ú-+V¬Ø½{·££#™L¶³³Û²eË©S§Ä+Ðéô'Ož„‡‡kii,\¸ðܹsݪÐ%2™üàÁƒ;vxxxP(MMM;wо(I$Ò½{÷vïÞVÐÒÒ ½uë–4ñöïßÿÕW_ÙØØH˜c±Ë”Peeew{vêàÁƒ111$ISSÓÍÍmÅŠiii=Û¡ôægŸ}Öî?d¼¨42©‰ÝöK¦O%sy\Á²1 ÿ™†“Íûáˆ$¢ž!Í#Èfí1ë5‡ÆŸ®°\¾›líˆÓ “-ìÌo±ÙØþcGÑ'|Öî?zŒh`ì|â‰nðx<…JÔ10œºÈâ›_ìjp8tjÛuÒØÊhSàD±}Tû–€uëÖݾ};==«€ ÌÙÛÛ/\¸pÍš5X)©%žæU7Æ|ÿ¾ßܓ܊¡{"=æÎ%ijb˜2«¾t¨t×2mßP§c°¤àþ½p ͳóCÑ—çâsÒzh¦A©0uk 011©ªªÂ$HITTTȤ%RWt-Jí‡óΪ<}º<䯜ÌJ}*hnäÕVÔ^?ñîu½ÓºÜPÞöK?Ô²ØZpѸ¾«ý<&&&µµµ€@€ýDú¢†††ÖÖV˜@´[rýEá±[)û¶nåQÿøfýã‰P]|¦tÒ'QÁøìÖvë?‰¯õ5í[lllAii)&Ñ@˜Cg êýèHYèiU4´ðþ?"ÀX[“B"re0ªH8¸£3h4ÉÐ GÒ [Ú›ÌûÑéè½v(ˆPØÌbõ3l›¤ŒÙl©¯…aH¶Ú· £ó ÑùÅ ¾í [ léÚ!RÆlFKp8`I×nfÁ$຃Çé‡uíq›YˆO k›ÜÌaNßÕ¾%ÀØØ˜J¥¢SöB}PEE‰D244Ä:Hy¡?!…µm¿úvt·Q•¦í³Ð?“-½- (ªk õ5í“gkk+å<êú©ªª266ÆvÞbHÉÑ45IÄbF[àjª'hdb$%v=SG“l¬ý~O |WßbC§a„¡N¦Štpp@W(ú šštÒ:ú¸šëe–·ýê{X°ê˜˜ÌmuK ƒ1ÀÒ@ô2»¢ž/ºšÁÇ}W'I€»»ûëׯ ¤ `IÞQ^'þ’Ïçs0 ’ŸÉðK2Êë4ˆøþ¦z†a«“$ÀÕÕõíÛ·’—0ÔUmm-ìuÉÃÒ ½¬- p1Ó#àñ­µ C‚º„ H ƒénÞ–¼*g¸˜ê“põ ¾«ó$€ËåªîüGPoÀ–H, jšØ•-èKªq€%U%ƒÇ!ùieÔq¹ÜÁ&¢’ô²º6Ô^'I€³³3@ÈÊÊR|4æjjj`KÔ¥[c—×ö«?ÔÑ„S “¥Æª¬Ò¡’ÝÌÞÿê „È‹üê {É[Aê­“$€J¥º»»ÇÇÇ+>sðq$ m i€…Á‹üjQÉÀ~&Mµ !|Œ¨ÄZªªmEC2ß1ÙÜÁöpf°>­óGA/_¾Tp(æø|>“É„ i ¶7}–ßvëâh† Â¦Š C‚$A@Ë»wÃÛæ{–W¥«©án‡ôiM’’’`ßÀ¾†Á`…BØI#ÈÞ$µ´–Åy¿¦°¹Õݰ±¤Û¨ i©­imiçn-*yšW1ÐÎ'éÛ>š477Ãn}MMM ¶@Òãf%"ÑYe¢’‰¬šË` ¤JKMtµDÝùBáý×¥cݬ%o©½Î“777– àh lÕÖÖ˜@Ò1Ð"ûÛÝËl[ll”«esC»¡è i.-ãf!ºí‘_]ßÂ7À Ó  ìužØ- ¯©©©ÁãñpÈ$•Ñ®VQ¯ËDóq45ÑÕbÀÑÅʇÓÐØPU5ËÏAT•UÚÏPÛÑXè eðÑ9"aK@_S[[«§§G$¶_[‚:5Ñæ”ÉJ*®A_âq¸Y~vMùØFuÄ,(0 iŽp1•\K-œèaƒaH’øhàï•ÅbÁ•Áú8SÔ-¾6†ýMõþIÌ•DøöcÕ×·ÖÕIØ R¼¦Âü©Þ6Düû/üô²ºìŠú™þöØF)II€@ HLLTd4¶à$PwMóéw9¹@ôD`°½©ƒ©^í›7˜} ¹¦º±¶î‹ gQÉåä:m`?8Môñ$ÀÖÖÖÁÁ!::Z‘Ñ@ت««£ÓéXG©’©ÞýJ™¬øÂ*QÉ¢ÁÎõy¹pÖ åQ÷&ÇÙLÝûŸ|—“ ¦xõƒc! ! Œ5 &} “ÉÔׇ3‡@ÝàcmècmxìI¶¨äÓ@G__X„]PP!ŸßX˜¿ ÈITò(çÝÛª†Áζ‚úII@XXXZZZuuµ„::©¯¯‡IÔ]_÷¿”TÀlá /Ít©áž6u¯_a„ªËy‹ðŸ jKNÄeö3_KêË$%Ç'>TX4¶˜L¦ž\YêžYþ8ï¸v¬WcuMSy9†QAÖ½Jÿ2ØÙX[-a4sn¦16@ïIJtttÈn[\øèœÁ UpI!ãsØ•‰ ß su1{ŸÓó…Ÿo§ÌäW ‚Úé: ˜:u*Ç»}û¶¢0[ ^ v0æl¾éV²h˜€·•áLûêä—Bœ@PqªÒÒ5pÈúq>¢’ y% ÖÚ±ÞF)§®“CCÃàààëׯ+ CL&“D"Ñh4¬TØŽ©ñ…U—“ÛÜ95@ÈfW¦¤aUŸÒÊdÖd¾Ú2Á×FAKš9üu7 q±7ÒÁ66H u¦L™rçÎ6›-ïh ÁI Þ °5þ<Èyå•-Ü÷·þVú´]S«ÒÓZêàpA¹C¤üq¬ŸÑòmC~¹“Âá ¶NòÇ00HiI•L:µ¹¹Î¤Þ`ÉÄÏá~ÌÎï2E%_ uõ¶2¬|þ °‹ |Õfg³jëŽÎÆÿu ÂÚ¦ÿ½Ú0ÞGªmlr’* °´´ôóóƒOÔ\8’ =­µc½¹“RPÛˆ–ð¸3Ÿ…°jj«22$o õ§±±òeÂêÑž^Vmk~õ÷S#Ý¥¡®)3©’À”)SnݺŇ˃ª¯††øÈ’U£=Mô>=õHøÿ[ÿ»§¾KL„ÓÈ "–<Œñ°ÐßÞ6ðÄÓ71Ùågæ%â¥ýª‡úi¯ŒˆˆˆºººÇË5C0 €d‚ˆÇÿ1+8¡°údÜQá²ánCLËŸÆ yð^Bö*RR¸õõ}*ú½¯jl]s=aqˆ‹Ÿ¶±AÊLÚ$ÀÑÑÑÍÍ >PcMMMÚÚÚXG©‰vÆ_‡ºýp%>¿æýC<wî‹P›]úÞKÈXCqIeZê¾OŠ&@ðÅŸµ4H¿N À66HÉu£(<<üæÍ›B¡P~Ñ@‚I$[»#Œt?9Ãå¿ÿÒ°Ò§ÝþfT}QaEj*¶±©“V&³ø¿‡_÷_ÒöàoLƃì²+KFêP`@H’n$sçÎ-++{ôè‘ü¢0“H¶ÈDŸŸ‡fU0¹“"*loº5ܯ29¹±¬L¶”\néÃWSÝ3‰ _•3ÖßL\3Æ+ÀÖÃØ •Ð$ÀÅÅÅÛÛûÂ… ò‹ÂL ™`að[Ä í÷R£³Ú~òWòšágWÓÊd`›@„Â’˜M>çæW£4ID´°‰Í›~,Æ×ÚhãÉ›CèV˜3gÎÕ«W[ZZä „!˜@ò°4Ôõ³AN3NĈ:àpàÌgCm ‹îßçÁ/“^(‹‹c×TÝÿvŒ ýýDŸfŸzÈâð®. ƒ# itï*™={vsssdd¤œ¢0“HNÎ 2×Õšuò!›'@KÈD­¥£,i¤Âûwù8iO¼KL¬Ë}{uñHo+CQáÞ˜Œ{™¥}>ÌDGÃØ Ò½$ÀÌÌløðáð‰€úáóù­­­páHhdÒÕ%a9• _üùX4g U#nåD¢°àöm˜t×»¤¤êôô+‹FŽq³ÞÎ(Y}-aÛdÿáýÍ1Œ R-Ýn/úôÓOïß¿_[ §W+, AØÉIS½Ûߌ¹žV¸úZ‚¨ÐH›½l¬–€S%àr1 OµTedT¦¦<ÙËVTø¢ ê“ã1K‡º­í…]hêév0mÚ42™|éÒ%yDa¥©© “H~†8š3dσôÓÏrD…ý µcWŒ×leܹ͇K”I¡"9©}çÈÎ/ƒûÏ?{7³DTÁR_+eí”ÁÖz¹7o4—HØUÄkmͼ%¨|÷ô‡‰3ýíEåµ,ö„C÷B$òë1ºšpf@¨'z’H¤Y³f={«ƒ« 4 €£ y8þ¼P(LJJš7oÏž7ÐiÊ‘è+)mÏ´)¤[KGs³,x]ýú5†+•V#?ò&…ÓüèûñƒìLDå -¡¿E6´r®o®GÅ0BH¥õðÒâÅ‹sssáÂj£¹¹™D"ihÀ› H–X,Ö¼yó>ûì³+VÄÇÇ;;;£åxîèœ!ˇ˜yâáŸ/ÞŠêk’ˆW‡ý4Ƴìù³’ØX¡ ¯¯7ÈÌÏϽuÃMŸ’üÓ/+º¨¼¨®)dÏ-÷ôÇp[:lÀƒzŽØ³ÍÜÜÜO:5|øpÙa¢µµUSÎ.ÉRjjêÌ™3›šš¢¢¢FŽÙî]욨O%ñçãR&ký¸÷sÜ𸭓üö3™súQþÍ:«a#(úz {B <>¾&ëõWCÝöM¤Al»aK,ª ÿ#ÊÎHûö7cô©d ƒ„Ô@Ï»’.X°àÚµkL&S†Ñ@Ximm¥Ra‹"$B¡póæÍöööiii3‘ŸÆz]Z4rûÝ´éÇbZym÷ý<¬S×OqÑ&¾½q­&;K!Q+‘V&#ÿúuvAÞÅ/Gü1k°xp!!oÈî[#],­˜3¨÷zžÌš5‹D"ýý÷ß2ŒÂJKK l €d¢ªª*""bÛ¶mëׯŒŒ46îb!»i>ýn3&æMÙØƒ÷ª[Eåv†:q«&nëUþìyÁý{œ¦&9®°"5õíõëÞF”ÌMÓføµuD°ínê¼3–†ºþùy¨xfA=ÖóˈF£MŸ>ýÔ©S2Œ l €dâï¿ÿvss{õêUll÷t'é IDATìÆ ‚4[ ïoþlդІßm×^T‰Ê‰xü†ñ>/VO2å5ç\¹\™ž†…r‹{¬ŠŠ¼ëW™é©{¦þ÷ýx+ý¶Žº ­ÜÉG¢~¾“|xvðÞéƒð8†qBê¤W¹ä‚ RSSSSSe „Ø'ꥒ’’Ñ£GÏŸ?ÿÇÌÊÊ7˜Rý.ëÒ?%OŸ²ëU¬U@ÈãUgf¾¹üOeBüÂ@»‚m3™äG#·}z!²ÿá+÷-—Ëë›ãV…¯ã;@r‚ëý¬“'Onii‰ŽŽ–I@&&OžL¥RáXHJ¥¥¥K–,¹ÿþ·ß~»mÛ695#ÝË,]úw\C+wçÔÀÁÎí~¹|á™ç9;¢Ò‹ëõ­¬éÜuÌ-rÿVr›X5Y¯™9Ù8¡pAóê1žâ½ÿP©¥µKÎÇ¥•Õ®åµnœ7…$UçJ+¿þúë©S§òòò°¤‡z8Y¸… †‡‡çççÛÛÛw]RJ­­­†††XG©·ÿþ-[¶˜››?~ü888X~Çën•¹iú¦È¤¯/Æ{šu`FÐ`{SÑ»Düâ—…Cú_K-Ü•‘|ç®–®®¾« ÝÉ™HV²ôÒPVZ—•U_Rª§Eþ)lÀסn†4J»Z5Mìõ7Oƽ ²7IY7ÍÍ\“`¡>EIÀ¸qãìííÿøã½{÷ö~o&àãH÷îÝ[¶lYuuõ¶mÛ¾þúk"Q_ ’i‘‰{"~Üååø!»oÍôsØîëh¬+ª€Çá"|ì"|ìRJjO=Ë9—Z™˜¨ca©cÛO×ÖÛlAVEE}a!«¸¨µ¹e¸‹Å¢/GLò²!ÛßÜ·pù‡c³¶ÝKÑÕÔøûËáŸøÚÃæH1dðo‡Ã-\¸pûöí[·n…ËTIVYY¹jÕªóçÏ?>::ÚÎÎN‘GïoªwgÙ˜¨×e«¯%¸nº<'Ðaý8cñ:>Ö†>Ö†¿E ŒÌ(¾˜Xp÷y\É“':æ¦4+k]kŠ®âæp¸e¥ %%¬²RN+ÛËÆhöh÷™þö[þ­<þÑÇÙ;£ÒØ<Á£Ý×nšO¿Ž}ïÑMœMôœMôfú¿ÊÄK¬ÂÚ¦ê¦Öºf6£™Ãhæ°y‡Ç¼_§@ªÇáèZ-²™®E±¡ÓléÚºšRý~ó…‡Ùï.%çßH+jæð'zØD~=fŒ›U»¦ „,{ ,Y²äÇܽ{·®®n×µ!eÂåraKTPP°fÍš«W¯zyyEEEIXX©ô7ÕûuJÀÖIþ1ÙåóV]Møæâ³'ÓÑ®V£\-=-é:x{#{#Ö詪ÆÖ˜ìò謲;¯J˜-œ`Ó­“ügøÙÃÿR‘e0wîÜ5kÖœ;wî›o¾‘án!€I@WUUµgÏž#GŽèëë?~|þüùR.¨<xÜh7ËÑn–Gçn¿*¾žZ´+*}õµSj¨³Ù`{Ó`Ór½ÿ~Wß—Wù,¿òInEzY‡ì`²fŒ× »N‡@æd™Ðh´Ù³g>|øë¯¿–yç[H®`Ÿ€>«¼¼|×®]'Nœ Ñh7n\¶l™ª¥èÌ!’XTs7³äþó¤ëwîsŒu(–îæžV®fúv†:fºÔ§ÌNqëMe}Fy]f93½¸¢$ûÎÔÞÅÂh°ƒÉºqÞa.–R>2€ ¬Èx@êW_}uôèѧOŸ†„„ÈvÏüðù|¡P“€¾¦°°p÷îݧOŸÖÑÑÙ¼yóÒ¥Ki4µº[%àqíŒÚsž]nÍ‹:µïÇø‚êW匔’Úó ¹,@"à-õµ¬ôiÆÚš&:šFÚ#š&‘ÐIZPß­jl­aµÖ4±Ë˜Í% V#›‹ÅÎPÇÃÒ`Š3ýÀî½·ü7nä0EŸ*õ”Œ“ÀÀÀ#GŽÀ$@…p¹\ìØw¼|ùrÏž=×®]£ÓéèØ?-­öêÕI||ü AÑ1h ‚€«„Á*ªk*a°Þ54W6´f”×Õ²Ø5MlidsÂ÷Ãt(Ô3j0™ÌuëÖõïßÿÌ™3K—.ÍËË;v옯¯/ÖqAXJHHðòòRü°—ÀÀ@—ššªàãBP(b˺uëÒÒÒnݺ¥€cA= Ò}¸\îþýûŽ=ºråÊâââ;wöÁyñ Žß+Õ¯_?8[¤‘øøøÌ;wÅŠèÈfHÙ¨nŸ€k×®¹ºº®ZµjÞ¼yyyy7nì8¨ê›ZZZ222ß!åïïç „T‚‚¦³Ø¾}{eeåÑ£Gs8¨[Tñq@UUUDDÄ´iÓÜÝÝ_¿~½oß>øó‰KIIáñx˜´¸¦0¤:”XXX|ûí·[¶lŸüRh *œ!rüøq''§ÌÌÌØØØ7n8::b¤tâããMMMmmm19z```QQQUU&G‡ é)î{íÚµ;wîTØ!)ñù|<¯c8 FDDÄÒ¥KçÏŸŸ˜˜Ø§–Ä…ºE‘ëu€Ãá± ‚¤¤¸$@[[{ݺu,..VØA!i•èðèÑ#OOÏäääÇ8pΠI€m §§çèèŸ@ÊO¡-À‹-233Sð^P—’wk×®9rd```jjêàÁƒ±ŽRjåå奥¥&€ÀÀ@˜@ÊO¡I™LÞ±cǹsçà¿ ¥" •9 hhh˜0a¾}û>|åÊØêRBB@ð÷÷Ç0tMa¡Pˆa Ô%E÷ûä“OÆŒóå—_¢cÓ!%¡´S9eeeùúúfgg'$$,^¼ëp ÕàêêŠí£€€€†††ÜÜ\ c€ .aÐ!üÀyyy‡Vü¡!Õ¢§§§þ…¤Õà@OOO …[=!%‡AàààðÃ?lذ¡¢¢BñG‡:ÂápJØpåÊ•1cÆŒ1âÉ“'–––X‡© @’’‚í³€†††——œ7RrØ _»v-Nÿé§Ÿ09:ÔŽ&¿ýöÛ'Ÿ|²fÍšþù‡J¥b¤J²²²X,V@@ÖÀ¾ À& ÐÔÔÜ·oß_ýÜ„:Z³fͪU«8°yóf•˜½R* ZZZîîîXÒÓÓ[[[±‚> ³Iâ&Mš¶råJtº:CJÕ°råÊ={ö9rdÙ²e²Ý3‡“wJ¡€C( e>Ó¤¤$oooeð‚.'˜––&Ã}*ÃeÌápV¯^ݯ_?‰$e0íö©Ì×O_ƒåL±‡ÊÊÊúí·ß0ŒÊ”¬Y³æàÁƒ/^\´hÖ±@ª*11ó(;;;CCCõ{"ðË/¿ìÚµ«¨¨òRX&ŽŽŽ¿þúë† ^¿~a’$6løí·ß.]º4}út¬cTUkkë«W¯”$ Àápê×7ðâÅ‹€«W¯r8)¿:Q†/¨#Œ×ŒY¶lY@@À‚ àC>nÇŽÛ¶m;yòä”)S°ŽRa<OI’ ¦Ë ¢S¿O™2ECCëX ÞÂ8 Àãñ'OžLOOß¿?¶‘ôe˜·œ9sfíÚµ¿üòËgŸ}Öi…NŸ vú”±¥¥eñâņ††ÚÚÚS¦L)**úØA¹\îÎ;½¼¼¨T*•JõòòÚ½{7ÇUˆ‹‹›;w®¥¥%‰D¢Óé£FŠŽŽßCaaáäÉ“i4š¡¡áW_}ÕÒÒ"ù4ù|þáÇ dll¬¡¡ann#ý9òùüøùùÑh4*•Ùå[€óçχ††êéé‘Éd‡U«V544ˆHr…îž)†étº½½=Ö¼XPPP]] Ôâ2Fí;* ¾Ë£ÀNÊ QÛ·o×ÔÔ|ûö-ÖôQ.\ ‰XýáÇ$iåÊ•êtz­¶+D_N:Uüò¶´´¬««ëXŸÍf‡„„tüç0lØ0.—+^_‡»qãúnmmm»Ù D‡þØY|ñÅþ vyŽ\.wÔ¨Qn.á-¡P8{öìŽo¹¹¹544HS¡gŠ¡yóæ………aE›ºº:wûömD-.ãŽ{™oTü(;Í^|®JdûöíöööXGÑsJñgàñx~~~C‡ …XÇÒa˜¼zõJ[[ûÓO?•ü§—þÛÓÆÆ&66¶©©éÑ£GÖÖÖ€U«Vu¬¿cÇ€žžÞéÓ§««««««O:¥££صkZgìØ±÷îÝ«¯¯çr¹eeeûöíøûû£ï®ZµªÓÃIøjC'<ؼysYY—Ë­««‹ŒŒ5j””ç¸gÏF;pà@ii)›Í~þüùäÉ“%¿uâÄ €……Å¥K—jjjZZZž?޶–¯^½Zš =8S ¹¸¸¬]»ë(>àèè¸qãFD].ãNODòQ>všÝù•Ld#11‘H$>|ë@ú¢¿ÿþ›@ (þ¸ÕÕÕ¶¶¶AAA­­­’kJÿíyëÖ-QÉõë×...룓Ÿ9sF|‡'Ožxyy¡/cbb&Nœhjj*¾Î2…BAßíß¿§‡“ðÕ†n2jÔ¨ï¾ûîäÉ“¹¹¹Ý:GOOOÀñãÇ;îYÂ[èJzOž</ÌÏÏ8::JS¡gŠ•††<ýúu¬ùÀœ9sF¨ËeÜé‰H>ÊÇNSÂ!TLdfÛ¶md29##ë@úœ‹/âñx”Íf;88ÔÔÔtYYúoO&“)*a0âßDâõ)  Ý¡Ñ·ššš‚üóÏ?{„‰V&“ÉNÂWÛ³gÏlmmÅw5f̘ªª*)ÏQSSP]]ÝqÏÞB›@Àãñès\t·$Iš =8S¬È`0rssÕã2Æê(œ(Q€ÇãÏœ9SPP°qãF¬cäëúõë{öì9sæ ÚŽÝ%€xé§OŸvZS¼”º_¿~«999îÞ½+^xûöm€³³3mß±c‡““z¿õðáCñÊèn;N2"‘ôã?^¾|9== êDÝå9¢Ý¼y³ãn%¼åææxùòe§7ÒTèÙ™b"11ÑÏÏë(Úóòò"“É/_¾T›Ë¸.)5Ù6,ôÞŸþ‰Çãÿûï?¬éCþý÷_E^ zzzK—.•~“áÇÂÃÃKJJoß¾meeÕîF_v«G•¾¾þŸþYSSSSSsæÌ===ðÿU€µk×ÖÕÕ1™ÌK—.¡ßà¢=ô GÕ!CÎ;WZZÊãñª««wîÜ  R©Rž#:·¦¶¶ö¡C‡ÊÊÊØlö‹/ÐÞÞ:}ú4ÀÔÔôĉ………---l6;''çøñム’¦‚ u ´µµýå—_°Ž¢ß|óz\ÆH‡Æü.Òqå¼~zFÕ(ãŸaæÌ™––– ë@úŠK—.)ì$‡Ã ðñña³ÙÒoÕî^ n'ªƒ¾l7ׄ±UC† „††¢“ íÚµ«Ý[óæÍßCÎu<`Ñ¢ERž#—Ë1bDÇ=H~ A «0HSAU†VUUîß¿u @gESËéðÞåQ:n¢„×OÁ$@öjjjLMM¿øâ ¬é+Ð$@1ã37lØ ¥¥•••ÕÝ OŸ>Ý¿‰deeµeËÑ¤å¢ èK‹µ`Á}}}--­I“&´« zÉf³wìØáááA¡P455=<$$dÆŒXÇ¢æ:Ž\’‡õë××××ÿñÇr= Ôg)s€ÃáüýýÕo9AH (o€ÇãÏ;×ÜܼpáB¬céäšÄÆÆþþûïûöí333“ßQ >«´´´ªªJi“@`` l €”ò&ccã¿ÿþûêÕ«GÅ:u&ïÇ\.wÉ’%aaasçΕßQÐç[òÛ?¤Ì ‚Ö|T@@@~~~mm­äjð2†L©“ÀСC׬Y³råÊW¯^a‹Ú’÷ã€;v”——Ÿ€” $áêÕ«B¡0""B4¬’!òØù÷ßokk»bÅ yì‚‚$%%)y „}!e£IÀÀÀàÚµk «W¯Æ:5¤¡¡ǺMwîܹyóæï¿ÿŽ‚ä!//¯¡¡Aù“€€€€„„øÈR*ª‘<==Oœ8±wïÞ3gÎ`‹º‘S V­Z5yòäNg´… YILL$“ÉR.F…!t9At¹RD¬è†Y³f%%%-]ºÔÝÝ]ù³~B"‘€Ö=qâD~~þ;wd»[j'11ÑÝÝL&cH¼½½ÑåÑw H¨LKjÇŽ~~~3gÎd0XÇ¢>äÑÐÔÔ´iӦŋÛÚÚÊp·Ô‘ò÷ D‘ÉdØ7R**–H¤Ë—/s8œéÓ§ËüεϒG°ÿ~‡³aÃî‚:iii¾¾¾X"´[ÖQ@PK¦¦¦ÑÑÑÉÉÉsçÎ…]ldB檪ªvíÚõã?ÊjŸÔ©ìììææfx™œ IDAT???¬‘J```ZZ‡ÃÁ:zOõ’€««ëÅ‹¯\¹²}ûv¬cQ2o Ø·o•J]¾|¹¬vA“’’B¡PÜÜܰD*'##ë@ è=•Lcǎݱcdž .^¼ˆu,*O¶I@uuõï¿ÿ¾fÍež¾ R©©©îîîhk–òsttÔ×ׇO 塪Ià‡~X´hÑ‚ âã㱎EµÉöqÀÞ½{i4ÚâÅ‹e²7’,%%E™— h]N&òPá$°ÿ~ooïO>ù¤¢¢ëXTXoZîÝ»÷Ýwß½yó}YSSsèСï¿ÿžJ¥Ê2DêŒP(Lû{÷×ÔÕÿüdÂÞ„ "#'àV´ZµVk­>v¨µ{§ËŸ£¶OmíTëªUëq£ eÙ{²ïïØ@Ñ@à&áû~õæäÞðA ùÞsÎ='7w„ xѬôŠat:ýĉ$)..N(âÇP §hllüæ›o£££;¶k×.“Í›7ë:#¨¨¨Ô€âp8åååp“3І] „ììì._¾ÜØØ¸páB˜s;4Ãèîî¦R©†%''?ñÄß}÷Ýĉ»»»u€dggS(”¼ƒhËåbÛ =aðEBÈËËëìÙ³YYYkÖ¬Q©TxÇ1<Ãé ê ‚U*†aB¡ðâÅ‹®®®±±±G… ŸÀˆÊÉÉ  ÓéxÑ‚­­-›Í†i@OC€Šˆˆ8räÈñãÇßzë-¼³‰D$‡Ö îY­A&“i:–,Yk9€‘cX³5`ZÐFR „æÍ›·gÏž]»víÚµ ï,†‡J¥¹'àA{ÛØØìÞ½[ÝO€Îa–••eX³Õ8@OÒBµzõê’’’·Þz‹Íf/^¼ï8†„B¡ ­èê꺿 ‰&&&IIIl6[é@mm-ŸÏ7О€öööªª*OOO¼³€±ÎxzÔ¶lÙ²fÍš•+W&%%áÅP©Ô¡ ðùü{Z‰D:{ö¬¡,â Tvv6‘H Å;ˆÖ¨T*L úÀØŠðÛo¿-^¼xÁ‚)))xÇ1C¸ÿN'pìØ±iÓ¦é"”íëëkˆ SÒéôàà`úÀØŠ„‘HÜ·o_LLL\\\NNÞq ÇÁ=-ß}÷Ý¢E‹t €Áè¬@5.— =@a€þÙqxüøñsçÎ---Å;Žòp@ÿ5šˆDâÛo¿½qãFÝåà tV ‡ÃÉÉÉÑíþÝ q!“3gθººÎŸ?¿©© ï8únÈÃ===êÿ!‘HO=õÔŽ;tš €566¶µµtO€D"í@1™ÌÓ§O#„ââ⺺ºðŽ£×(Êz …z•F2™7‚Ñ‘M  ·ðóó³²²‚iwFu‹àýœœœ.]º4mÚ´9sæ\ºt‰ÉdâHïHäJ¾Xª$«Ûø—ï4JäÊ^ùÝeþè’ …L§¬LiV¦4+Õ„ò¯_¡Pˆa@ðöö>v옡lç Œ@vv6›Í¶´´Ä;È„ˆˆˆŒŒŒM›6áŒiF^ „<==ÓÒÒ¦OŸ>}úô+W®°X,¼á¦K,+lâ6ñ*Ú•íwÿË!dZØLÿóësƒ¿‚ …ìeËô²ezÚšûØYØ`"„ƒƒÃ¥K— ÷í¢œœÃíPãp8ÇŽÃ;댿@¹¹¹%%%MŸ>}Ö¬Y—/_¶²²Â;Ñ(‘È•·jÚÓªZR+Zsë;ëù=!3ÅÇÎÂË–¹ ØÍË–ikN·2¥±ˬLi¦Ô~zeJžXÂÉøbi{O¯ºt¸^Öü[J‰°©ÑL•ó^Ùp²p’Wûd/‡HÛ_ÝÊÎÎÞ°aÞ)†…ËånÛ¶Ïçw$ ‡ÆÊûµ»»û¥K—¢££,XpáÂsss¼ Â&ÞùÂú„‚ú´ª™BÅbÐ&{9<7Õ?Ø™ìÌò´aj5poeŠœ,MïoÇ0t.)¥tI¸ÄÒõVMû®Ëœ¼E!'zÚÍr›ä:ÞÅZgßý´··×××zO€z;ÁÛ·oÏš5 ï,`ì+EBÈÇÇçÚµk111sçνpá‚!®12†Ý¬j=–U}"·º¶³‡Å ÍðwÞ½bòT‡«‘˜®G  ¸˜)qÿ<Ä0TÒÒ•ZÙrùNã—óß;‘ébÅXÊ^Ξâí@„ ƒ@w²³³B†^ØÙÙ¹»»gdd@p4†Š„¯¯oBBÂŒ3üñS§N™˜˜àHî4wý–Rò×íÊÆ.‘¿ƒåš‰¾óƒÜ"=lIÄQýÜ%P€£e€£å³SüU–UÛ‘PXw4«êÛk…ަËÃ=Ÿ›êä4v'dÊÎÎvqq±³³Ã;ÈpÁ’Awc«@?þòå˳fÍŠ‹‹;s挩éÝAªPþu»ò×ä’”ŠW+³µ“|Ÿ÷ qyø§¬B¥*kí®lTwk:…M]âV¡¤]$å‰$=’î4£SX š5ƒfoFw²4e[3Ù6æž¶æ~ö–ÒÀ·˜ „HÛHÛ㋚øG²*÷Ý,ß}µp¢§ÝsSVr¼î¹Ë­Á¬@5.— Kk|Ææv便¥3fÌpww?þ¼ÁÝ7ØÜ-þæJa|jIw¯lq¨Ç˱AS¼9^©Â ›x©­·ëÚoÕv–¶ðå %BˆN§Ó˜æDƒD£“it2N¢pŸR&WÈ$ ‰D)‘b"‘D(ôJBd2ÑÏžáÎ w³™ìåâÂ"[v"«¶ã—ä;ûÓË)$âÚI¾ïÌ pªåíí½zõêO>ùï Õ’’2uêÔêêj¼³€!Ú¾}{|||EEÞA†hŒ¡òòòØØX{{û‹/Ê}ƒ"É—óH*VaØú)~¯Ä³mžá¨Â°ÜúÎKw‹›2«[ÅR9ÝÔÄÄÆ–fÅ¢³¬L¬¬hL…:´J¹\*Hxü^>OÊçKÚÛ{Åb*%‚m;7ÀyV€K¸»Íƒ&Ôó{v_-üåF‰ Ã6Lx{v¨­9}h1ÀØÔÕÕÅb±NžqA°.i¡X½zuggçùóçñ¢{öìÙ´i“@ €U· ”¡÷@€BmmmsæÌáóù—.]òññÁ;BÕt _<”šXTÿìÿO†;ZÜ;‡®MØûݵ¢Ý׊…™%ÛÃ&0ÐÜÑ —¨ÕÓÚÒQ\ÜUUmJ%¿8=à娠û¿N‘ä³³Ùß'MñvøyõT?{X„ ,00pÉ’%[·nÅ;ˆn7.++Ë8îwƒ ½€ÞW„²³³»víš‹‹ËÔ©Sóòòð £Â°¯‡nùûN ?ñ•y?¯žzÏGfs·øåÃi®ïÚy¥ØÄÏ?hå*öŒ™z[ „Ììñ©ß¯vôH4Ï2hä_VO;ö¬ýéå1_iêã艼¼¼¼Sè˜f;A¼ƒ€±Š€½óÎ;ñññ[·n}ùå—Uª¼ ½]Û¾õxs·8ýÝÅ+#ÿ5Ìy® Îïã£Gó½çÌuŸ1“jnTÛjP ·˜ŸùóOÝiõûøè‰œšþÏ. cg¾·„/–Fl;~³ª§Œ@/`–ŸŸ?~üx¼ƒè˜ƒƒƒ››[ff&ÞAÀXEÀ­[·îøñãñññË–-ëíí‰/q<§zú—gÆ»Xg¾·¤ÿ{b™â…ƒ) ¿ODÎn¾Ë—[¸ÿ­óLߥËÉî^K¾¸nßua¿­Œü,3Þ]2ÑÓ.ö«³‡oUâ૦¦F(_€âp80-àŠ€Á,\¸ðÚµk)))±±±º}ñÏ/ä.ÿùò&ûÚ4Ǥ¯“?¯¡3dËñ?2«9¹ÿêúûÒ˸;NuMü–.³“‹Y¸ºú.]ÖEgNúüô/Éw4íDáËe¿_9å³sY›§@0ååå±Ùlsó7Í2h\.·­­íþwFçååuãÆ SSÓ¨¨¨œœœþO½ûî»qqq‰äAçÞO¡R=½çê׋NnšýêŒàþí¥<³'ÉÂ?ÀkÁ cìn³K11ñš7Ï:8xÃÁäµ\ïkÀÆé§6ÍÙ“Z¶ò·+r%Ü20¶儵ððp2™ ÓÀèƒ"à‘888$%%…††N›6-11QݸwïÞ/¾ø¢®®îóÏ?Ä×QaØ ’eUÿù쌅!îšö©|ÁwâSËØ±±®QQÂXÿ¹g‡=sÖ¡[•³w't÷Ê4O-vû{ìÓyµkö\ƒUÇ”¼¼ùäc=vðàÁ+W®<ûì³!•Jõÿ÷¥¥¥ò"/N;˜QqrÓìÅ¡šÆVAïä/ÏܨîðŽ‹cÑ:hÃgÅf{/Z”ÑÐ=qç鯮¾e†ç¹&¼<÷t^íónÀ¸À!ªªªŒïþ@ .— =`ôA 2™üóÏ?oܸqÍš5‹-Ò¬¸L ^|ñŇžþòá´ßRJÎlž3wœ«¦±Ž×µótuÊç±% ;»‘Šn°L­m|/n’'~~º²] iöuºøêü¿nW¾ø'Ì 1 3Öž„—ËÍÊÊR(xc Ú!‰ü±­­­L&Ó¬ —˯\¹ròäÉANüߥü®íY;}V@ß>è¼ðm'y$º×¢Eƺ ÀðQ ¯…‹D¦LÎŽS¹õšöÉ^û×Åþš\²í|Î §ã——Çd2Ùl6ÞAF ‡Ã‹Å………xc ÚQ(Ë–-ãñx÷ìD"qÓ¦M"‘hÀ³ŽfU½ýwÆ7+&õ_¨¼­{Æ× r†{Îõí9ã_Œ§i¬íì™þÕ9©‰9{Þ *€‡#R(ìys1KVÌ®„ж¾qõ“ý?Ž _÷GÒé<¸½Ê˜ñ¬@5"‘ÓÀ(ƒ"@ ¿ÿþû÷߯T*|V¡P|þùçÕÕÕýëx=«â¯ÌrÛº8RÓØ"OÛu¶‡L÷œ;D¡Ü÷J``DÙsö™‰ùô]gëù=šö„/ c¯Ý›ÔÒ0&*•*??߈gªÁv‚`ôA ??¿µkךšš‰D‰tÿ*•꥗^Ò<I ¿Otc™~nñŸnL¡D>û›Dž’ä9o>ôh‹H¡xÎ'$Òf~s¾K|÷¾Aí[ãcg±àÛÄþ7£QUU%‰Œ»'!Äápîܹ#@- FZ˜=›M53³ ‡cª±ÉÆßÏÄÂòã~ËÂ<}í-¶œƒÎƒ4v îËåÁv‚`@0\õüžåïÏ› YðNs×¾ô2»ðH þyG@´‹Œ¥†k×å¦éÓ}4-¹Í`YYyzâ˜j,³tw7·µýðtß~¬+"¼<¬Í¿¼˜c*0B¡°¶¶v ...ÎÎÎ0-Œ(†¥K,û-¥dsÌ8M7@y[÷ßÙÕ6!¡h¬,m¢lLJ&Ô6ÝÝKD$¼:#xïÍÒVA/¾Á€VŠŠŠ0 ƒEBˆÃáÀ´0  –ýe* {vŠ¿¦e瞊êy"©ú¡¥)uv ËѬ*|SGQTTdnnîîîŽwÜp¹ÜžžØNŒ((†BªP&Ô/ gkZNäV+0 Ò7–l6H<’U©iYæy±¸A$…ÍÚõúÖ¾Ñ&((ÈÌÌ ¦€EÀP\/kJe‹C=4-‡2«,\œI4*~¡Àˆd2ÓÍí`fߥÿ¢ñî2¥òrIŽ©À£˳ÕH$RXXL # Š€¡8_XâlíÀ4U?I×J™ìÁϸ°ð`߬lá‹ïŽX™Ò"=lÏÖã› <– #Š€¡8_X?wœ«æá•’F¹Reá6v/õÓÍCèBQߥÿœ@ׄ(ôÇknn†"@½`OOÞA€Ñ‚"@k]¢ÒÖ®™Κ–Ä¢zs[² ÇTàAH*ÓÁ.±¸ïSf€s=¿6Ôgpk€—ËU*•° 9Ph-¥¢…B"FyÚkZÎ7š:»à ÎÔÙ%±¸o¡@.ÛΔJN.oÁ1\QQ“Étuu}ø¡FÍÕÕÕÉÉ FÀÈ"@k7«ZÇ»X3hw—lî×´w›;9á› ÂÜÉ©µKTÕq÷ÒŸB"†»Û¤UA ¿ŠŠŠÆò­‘‘‘P€‘E€ÖnV¶qÙvš‡i•­"ag7È)_ [2™”ZѪi‰ò´¿YÙ†c$08˜¨Áårá.A0r ÐŽB¥Êkè¼§0·f‘(SÁH$†mjeߥ?—mWÜ̇Õô§¾¾¾©© ï À8A ;Í]R…r¼‹µ¦%½¦jÝúŽnk›^Ó¡y8ÞÅZ…a<#éèèhmm…"@Ãá‰Dè #Šíä7ð¨db€£¥ú!†¡ü†NSkëÁϸ3±¶.nâ)Twwô´a2éÔüÆN|SÁ­ý™››ûûûô0B ÐNaÏÏÞ’BºûïVËöHd&Ö,|S‡2±fÉʲÖnõC:Y6òñMTTTdiiéâwÜÜÓÀÈ"@;åmÝþ–š‡…|·Z1¾ IDAT™XA ïè–V"¡¨©ïSßßÁ²¼­ÇHàAŠŠŠñN¡G8έ[·`;A0 ÐNu‡ÐÃÚ\ó°²]@71!QaË}G$‘ffm} ¹³Ì«;„8F³ïÁår…BaII ÞA€‚"@;5ÿ*jyBš¹ù Ǻ¬BV„‘Ü«M17¯éìûÔgÛ˜×ò„†c"00(îljj Ó @Ðj­ m× (´Ð#•óDRwk3MKU§hf E€1}Ø?Ñ̼²ß¥¿»µ™D®löâ ܯ½½½½½Š€þÈdrXXL ÷ÐIÑE€Z½!Íæ¡:ž˜Â`à—hą߯ÂoÉÅ2ÕŒQËiªŽêŸ)ÐEEEn ¸—Ë…ž0 ÐBG!dcÖ·QP{O/ìd(Èt^DóPýsìè×ôAaa!‹ÅrttÄ;ˆ~áp8"‘èᇠ (´Ð)º·à÷HÉ4})zrSª?z:¾K6—’k]þâlAúÅþ`JEÛŸßÜy:"gªYÎdӲ磻oœAiÔƒý‡úÿñªÐ¬ÿÒ‘þ¯É¿t$+‚P¼*TÓÂK8Pö|tn´ev­p±wÃî·•=z1 ŸL§u‹¥šI,H ¨¦@À­‚íõ_uuõâÅ‹ÍÌÌlll6nÜ(‹ï?æÀÑÑÑ–––4ÍÛÛûí·ßîîìíqã5„~†ð…ÈCüvÇ$žHJ#“4[É•*±LF¦ëKPúìTÍÿ+@¿B0 ‡ÓôÖÎ;ÜÝÝ“’’„Báµk×nß¾Ýÿ€øøøC‡9;;9r¤½½],§¥¥EFFmÛ6ÀÛãCÇþéÕÄú‚"@ 2¥’Jê+¤ %BˆHÔ—CûÕo´û¡h©ÎdÓüù.õ_½†ê­(P?«¾dw}í+»'_¦Ú¹¨4FH”×—'ýõÉ,;æäy˜Bοø—º…ñ/L!·˜4le‹ê8ùBÈsëŸV3—“-mˆ4FH{ûa„ÿÚq~¯CA ‘Ð??55*‰Ôÿ!À]KK ŸÏ‡"`@Pè³Ó§O#„¾ýöÛéÓ§›™™EGGóÍ7ýøí·ßBþùçòåËmllLLL¢¢¢>Œ:~|€·Gmò‰0 ©BI%÷}äË”J„Hzð£‡ñ¯ªV¢ûn{WÉîŽyKkËBêKÿ!³‰[Û}ãLçù¶Ë7!„:Ï@Y/\«~V]p”½ƒÂ†B¦Ž$kªÎ×Õ ‰ˆ’ÊUš…Øÿ!ÀÜ0.—ûá‡677ìI=T]]ê?X3}úôþ „bbbÐ?ñšk÷šššû_PÛã‡|¢¾\ŹRÕ¿'@¦P!„úÑÐôÛgÃl—nw¼tBZoømlBrοŠÅÔ8²…µ(ÿ¦´±JÚP)*H'[X[LYp÷iõ/œJ‰©”H¥B*•¦(Áò½æ¨Q—k²~k¯RHD,ŪOŠŠŠlllìííñ¢"##‰Dâ­[·ð†Bý1¬T*•J¥J¥R©Tšþ|¹|€·Gmò‰zñf(H¢f:„™HDa˜^\JJ*BÎ/í »ù©t„àÖ•þÐÝýB]×O |>€” 'P¨¬9+B¼„¼„!ÖÜUÊÝU“é^ãBþû2ûÏ-d’ÁhS©Ð??55¥ #ëG ÔJJJüýýñN¡§,,,|}}aD@?±Ùl„Prr²¦åúõëýP÷oeffb¹ÿåxõí …BÛûƒw@-Ð(DõÕ¿æ!BSêE@µwEµìÛ©ð”Â.þå£uÿ÷|ÿX žF5|õzû‘ïåm˜L**H¯|s‰úYõ >ÿòQÍðÁƒ¨;ÿyçv&DýÆBvË6!„*_[Ôqò7YSJڋɤ’º²Ž¿–üg’ξաR©T!ù_³:ú?¸»sçN@@Þ)ô,¤·-Z„z饗®_¿ÞÓÓ“””ôÊ+¯ô?`Ó¦MêÃ~ûí·šššÞÞ^©TZVVö믿Nš4ÀÛã£okk‹:zô¨D"ò‚9Z ’Hý{ÕC˜J/ú“m—<ß°ûí–ß·iæá[/XÓynŸæ»/u§&3¯ÔíÜ\·só=§[Lžßyfoõ«4-ºv7 7ñ ê­,D™x›ú‡iž²^´N\šÓö×·µÿ÷œ®¾/”JôOé¦&•«ú?¸+--‹‹Ã;…þâr¹'OžT©Tú3¨½ýöÛ‡ª­­ŽŽV·<þøãuuušÖ­[—““óí·ß>÷Ü#½=>ÊñóçÏß»wïªU}ïÛ†iû…à7I 4ò¿&“«oTéÇ ²Ýê×]^ù‚ææC ÒhΞN/|êþQ|ÿdŠÏîó.¯|aâB¤Ò‰& óðhï¯N«Ÿu}ãkÛe©ŽîòÃïx´Ž{æžÿÑp}k·ï—­f,£Ø9È"ÍÄÄsœýS¯ÊÕÅw9,*…!D'÷¾Ð Wºººš››a8`§»»»´´ï à^ÖÖÖ7nÜX´hƒÁ`±XÏ=÷Üþýûï9f÷îÝ—/_^¶l™³³3…B1117nÜ믿ž›;ðÛãCÿúë¯7nÜèîîNù÷êZ}!€ƒ`@§òjÿpQúý³š{è/þî8uе/¾ÁÀ£àWWU_¾,ûáÙ&s Ú‹¿í]½Šãw4€B™™™\.·¢¢ÂËË ï,zJ.—[XXüðÃk×®Å; ¸kûöíñññx"è Ђ5ãÞÕæ-Íh ¬;k©¦™ (ÈäJ•úg ôAII NWO°¢P(&L€íA õ®ýW›g1è ¬;k” ËŒ¦yxÿN_¥¥¥ÞÞÞ0Ú=8˜t þÞ´ ¾jlöÎ&r1ìëedb‘“Eß6Ð꟣u¿²à î|êíÜœ€!€"@ 6ftS*¹¦S¨iñ±eª„ÂANúC!úØômžQÓ)$ Ζ #þJJJüüüðN¡ï¸\®\.ÏÉÉÁ;0Ph@@Öæµ¼¾O}ksBÑ#dÛ˜kÖt ]¬ü è…BQQQEÀC±Ùl{{{ºï€Úñ°6¯îøW ‰0ý¸K Ãz…=ÿ*:z<¬Í9Œ¦êêj™LÃ"22æ]"@;6fUí}E@³¦Âz»ºpŒ…D P(AN,MKU‡ŠýQRRB  x° Ð!(´ìÌÊoìÔ¬­àkoA%“zy¸†×Ë㉄@'KMK~/Ø™5È)`4•––:::š›CYöp\.·¦¦¦µµï À@ ñ.ÖB‰\37L$ú:Xõòxø¦ÕËã¹Û0M(w— lö¶Äã]¬ñM4JKK¡àq8"‘#@' ÐN°3‹H ä7ö]ú‡»±d8FBÚÑîÚ÷‘ŸßÀCA ?àþÀGgiiéããEÐ (´cF£xÚšçÔõS½„-mz²— †‰Z›§ù8h²ë:-LmÍa¥ }÷j¦]"@k“½R*Zú?T(b˜ Çz»º¤Ùd¯¾" ¥¢eŠ·Ã §€ÑÄãñ:::|}aŽGÅår333Õ»c0Phm’—}zu«âŸ???{K¦)MÔ“tô—¨¥Å„Jq¹; ÃPZekÿšà«¬¬ !=ŽËåvww———ã<(´6‘m/’*Ššøê‡šè,j¬ü,€£ž†úX?gÍÖAem]"ÉDO;|S²²2:îîîŽwƒ1~üxÃE€Ö‚œ­lÌè—ï4jZæs45«·«úSª„ó‚\4-—ï42éÔ07SþÊËË===aë GG¡PÆE>ø«Ó‘@˜;Îõl~ߥÿ¬¥RÙÓÜ2ÈY/¢¶6™L>;°¯8WP7;Ð Öeee>>>x§00êix§Þ‡b^kjeKw¯LýÐÅŠälÓUSo*0 ~Mµ§¥…ú¡X¦¸VÚ4/ÈßT ¿òòr˜¨-.—›——×ÛÛ‹w`Ø ŠY.Jv¥¤oDài®— ª nÔ7† ++×p½4-×Ëš¥ eÿŽ€/ ÃÊËË¡'@[G.—çææâ6(†ÂÖœ>Ý×ñ¯Û•š–'#½d2© ±ÇTà~=Mͽbñ“‘}EÀ_·+'²í]¬`a}ÑÚÚÚÓÓE€¶<==mll`Z&(†hy¸çÙü:‘ôîd@W+³p;~e¾©À=øUÎ,?û»[HÊSy5ËÃ=ñMúSßE€¶‡Ãi`˜ ¢eaž2…*¡°ozà†©þ]UUŠ^ Ž©@J¹¬«¢bãÔ¾Åh/7v÷Ê Ð+ååå ÃÉÉ ï †Ö ÃEÀÙšÓ§ú8üy«ïÒÿÉo:™Ì«€å;ô¿¢’ˆÐÓܾg‡2+`,@ß”——{{{¼ƒ.—[UUÕÖÖ†w`À º¦œÎ«­ãõ¨2häåá쮲R„ ~%]e¥‹Æ»[šRÕÛ„½çT=?5ßTà0+pÈ8@¸uëÞA€ƒ"`è–„²­ô½ieš–×g÷ðxÝ °z þ„ÍMÝ­moÍ Ñ´ìO/7¥’WDÂX€~"`ÈX,–··7L ÃEÀÐQÉÄUï½7K•ª»×þÁάX—Žü||ƒ„P{^~”—C¤‡­ú!†¡ßSK—‡{šPÈøý©TªŠŠ (†ŒËå´0P ËÆéµ='sk4-¯Ï êjlwvà ŸßU_÷æ¬`MKbQ}q3ÿÅèq8¦÷kllìíí…"`È8έ[·0 Æ ÁA0,¾ö‹C=v$ö­×1oœ[‹ukVŽ©@Kv–½ÕâPMËŽÄÜyA®ã]¬ñ  ÞŠ€!ãr¹<¶CEÀp½2#èvm{ZåÝ­„ ´s ‡WSÛÓÜŒo°1KÔÞÆ«ªÚ±8’øÏ„ó캎åͯÄ~"}åååöööx1T¡¡¡4 ¦€!ƒ"`¸¦ù8rÙvŸë»ôŸ;Î5ÌÝ®-7ÇTcY[NN “õc¡}ûÒn9—=ÞÅ– ÖC^^^?<•J …i`È Ðm‹9Š®–4©hçã‘üú†îúz|ƒA¦&^MíçKúºnVµžÌ­Ùº8nD×CÞÞÞx§0l°d(t Öß)Ößé½™šÙ93ü—„±›ÓR1¥×hc ¦R5¥¥Ä…¸/vÓ4~xêÖ$/ûþ-@@0|êí¥R)ÞA€A‚"@7>‰‹È¬i뿊ðŽÅ©¨§½¸ÇTcMGi©D ørWÓrµ¤éjIÓÇqá8¦‚aXUU•§'¬Ü0,\.W&“Áv‚`h Щ>ËÃ=_ù+Mª¸{éïkoñúŒàÖ¬Û2‘ßlc„¼··õVæ3B4Û)TªÍ‡SâBÜ`6€~jmm‹Å0'`˜¼¼¼¬­­aD :ó¿å›»Å?^ï»ôÿlQ›eÖx㎩Ǝ¦ÔW “Oõ]ôÿ–RRÕ.üú‰I8¦ƒ¨¬¬DA0L!22Š04P茫•Ùæ˜q[r:zîn$H#“~X9™ßPϯ®Â7›Ñ뮫먪þnÅ$™¤néË>=“ý´/[&¾ÙÀƒTVVÒétggg¼ƒ<.— w ‚¡"@—>œfJ%¿z$MÓëïô´À¦ä¹HŒc0ã¦è•4ݸ±&Êwθ¾nÿ·þNG}²f诪ª*"Þ…†‹ÃáTVVvtÀB¥@kðç§KætÊ޵ч2+ŽçTk¿~"ÊÛ†Qwí2,í9"0Twíª3“úãª)š¶Ä¢úßRJ~X5ÅÊ”†c40¸ÊÊJ˜¨\.!Û ‚!€"@Çbüœžâø¼òWZ—X¦n¡‘I×ňÛÚ[óóðÍf”ÚŠ ÍM×ŘRïî Ô#•oþ3uA°Û’ ¸FQYY tÂÚÚÚÓÓ¦€!€"@÷¾^¥Â° “5-!.¬oVD5ߺ%hlÄ1˜ñéiniJOÿâq®f·@„ÐˇÓx"éOMäD àþ@‚i`h Ð=kýð³3eWýš\¢iÜ0-pm”_í•KÒnŽÙŒ‰T(¬¹taÇûµ™}›̨Ø{³ôàúXW+3³‡ …­­­Ð +êuaÌh Š€1ÕÇá娠7¥W´õ}äûä$o–Yíå‹J¹ ÇlÆA%WÔ]¹ì¤·²ïÀÚΞ—§>7%`^+ŽÙÀ£¨®®Fp î¨·Tßu À£ƒ"`¤l_Âñ¶c.ýù¢X¦P·˜RÉ—^™o®’Õ$^€å„‡ÃT5—/Q{E—_ϤSÕR…rÙÏ—œ-»žˆÂ7x•••D"†te„ 4 ¦mA0RhdÒÉM³›»Åÿù㺦ÑÉÒô̦ÙÒÎŽú´TývCÕx3]ÜÜ|zÓ,ksMãú}׫;„g7ÏÕÌú¬²²ÒÑÑ‘N§ãÄHÐh´˜´EÀrµ2û}Mô‘¬Êï®iÃÜlŽo˜É//kÌLÇ1›ájʺÝQ\|ø¹Ø(ϾMèãSKeVüòôTwk˜ ``V Îq¹\è Ú‚"`dÅ…¸}ñÚ‘›ý÷š;Îõïçgµ6ܼ‰c6CÔœ•Ý–“{äù‹C=4WJ7Lyoî„Ç'°ñ‹´÷ê‡ÃÉÍÍ…íV qÅ…m˜°ì§ËéUmšÆEãÝ㟞ÖVXÐtû6ŽÙ KK^^söíoŸœÔÿÃ>¯¡sÉWs}¶.ŽÄ1ÐVuu5› E›.q¹\©Tš—ë‘-@0¾Z5ÕÇaÙÏ—ª;„šÆg¢|ã×LoÍÍi¸™óªéÖ­¦ÌŒoŸœ¼qz ¦±/ZüÃEªøÛqÌ´¥R©jkka8@·|||X,L Z"`4PHÄc/Ìr¶dÌÜu®±«ogáu“ü­í(.®½‘„©T8&Ôg†Õ¥¤´æåþ¾&úÅèqšö6aïÌ]ç˜dUÕžOÞxõm555Éd2¼ƒØN £ÄœN9ÿò<Y¾*Ü£îÆ²“'{Z[ñ 9BDííå§OÖ&%- q)ùtù=ÀÅ↨ÏO zåÉo-zÄ @mõêÕ¯¿þúþó˜&­‡`‘€E§ÓƒƒƒaD<"(ô‚¿ƒeæ{Kfº,ü>q󟩽r…æ)KSjüši7ßYìoF(;}ªæêUi·1Ìz“ …µII¥'OzѰo.Ú¿.†Å iž•*”¯½9wwÂ4Ç[ï/ rbiûúÛ·oŠŠZ±bÇÓip0\555d2ÙÅÅï F æ‚GE€¾0§Söÿ'fÿºØýéåá[§Uþ뢟˶ËxgñÁõ±fü¶;G4$'ËD=xE&¹H\ŸšR|ä/zGÓžg¦ß~ño‡þdÖ´En;ñkrIüšé‡Ÿ›ñ i€ƒ£P(GŽQ©T«W¯VÁ’Ìú¤¶¶ÖÅÅ 9'''G&“á(ôËS\ïÜÿ.u´0úÅé—§ %} he¤wÕÖ>kÚÙTxèÏÊ ‰‚ÆÆA^M߈Z[+/$:hÚÖøçúØÚm+Ÿ‰òí €HªxíÈÍIŸŸ²2¥eøøºI~Ãùr666§OŸ¾~ýú§Ÿ~:ìì@g`VàHãr¹‰$??ï ÀÀÄ@½Ã¶1¿üjÜ7ËÞ<–~*·öËeŸˆè›àC$–‡{>6ÞcFÙ΋ùeçÎY:9±ÆZº{ˆzZÒaÖ]WË+*îjl`ÛXìX5å™(_:åÞ Áã9ÕoMïî•ýôÔÔõ“ýu2 288øë¯¿Þ°aCTTÔܹsuðŠ`Øjjj`Vàˆòóó³²²ÊÈȈˆˆÀ; Ðw ƒ]lõT»Pò½ieS}¾Y1i¼‹õ=`:WP÷¿+×K›è K?k_“‰KÚÉ„ÂΊò®;%½¢žÉÞN¯Ïz,ÔxßÇ{aïÕ¿n^+mzz¢ÏŽÇ9÷,8|k×®=sæLVV\€êƒ€€€+V|òÉ'x1f³gÏvttüã?ðbü¶oß_QQw!‚žýekN_3}sÌ¸×ŽÜ ßzü)ŽÏ‡ &øØYh P\ˆ[\ˆ[M§poZÙ¯i¥…YÙLk3w¶¥‡‡‰µÖ“étEÂçókjzjªíö–Œ×¦ù®›äçe;@uRÝ!Ür.{z9—m—þîâHÛ‘Èóý÷ßß¾}{ÅŠÉÉÉTêPfª««ssÓâ^0\.÷èÑ£x§z ÃÉÜšÿžº]ÒÒµz¢÷ó¼íø@Å0”^ÝzävÕŸYU­]"ÓŒáêÆts3sp QFü“O)—‹ZZºëêD u¢n¡ ÓôÉpÏž“¼ìï¿ôGUu¶ŸÏýãf™·ó³EK'xŽè"'N|饗vìØ1‚_{áÂ…Y³f—ÊÉÉ +--õõõÅ;‹1kkk³··¿páÂìÙ³ñÎbä ½€áƒA$2Nÿ¹(düÜgg켘;eçi.ÛnStàòpO ùž##Üm#Üm?Š ã‰¤7«ZoVµ^+oͽY.–ʃiNa2ÉfL*ÓœjÆ ÓèdL§“¨‘H¤PÔ¯£’+0•R)“+d…D¢Hå="©P  BA@€©0S%ØÕ:&Üe’Wx”§}ÿý~î!U(ÿήþñzqJEËxë}ëbžˆð$âdÆÿüç?×®]{ê©§òóó®ŸÀHkhh@Á"#ÍÎÎÎÃÃ#33Š08( FaaaVVÖ—_~áùD„ç•’ÆÝW ŸÝwãÕ¿n®‰òY7Éïþ™ƒ!ƒ¶ ØM½Ü†¡ªAn}ga¯²]PÞΫ.­mê?bo€l˜¦žÖL'sO[Û`gV¨‹§­ùƒ®øû’7ñö¦•ýq³Œ/–Î tM|yþì@\V@þñÇÃÂÂÖ­[—@0Ê5˜õ^}}=‹Å25ÕñÜOp?‡K‡‚"À`]ýp†¿ó çVAïÁÌò½ieß\)ô³·|"Âsy¸g°óÀS äeËô²e. û×ê¼<‘”'’vŠ$B‰\¦TФw×+4¥’id’9ÂbÐX š5ãWù*næͪ:r»ª¸™àhùÖìñ«¹>N–x¾û›™™íÝ»wúôé?þøã¦M›pL2f544¸ººâbLàr¹0<†A©Tîß¿íÚµ÷\¿Ú3M^ŸòúÌüÞŸ·*ö§—o9—íje6;Ðev ËŒ§GùäVÆ{#Ü[ÈK¯–4],n¸XÜPÓ)tµ2[éy`}ÌW›á¿¸NLš4éƒ>xã7¦NŒwœ1§¾¾ÆF—Ëmoo¯®®f³Ù?ŒUP†7n455=óÌ3: Ä…âÂÙ¶˜s«¶í\A]BAýž´R aŽV“½¦x;DzØúØYè| žR…U¶ nÕ´§V¶$—·7ó1„MpµyŠë½ ØË¶{è`ÁèûàƒÖ¯_ŸššJùg þþþx§ÂÂÂ(Jff&`P†ýû÷GFFúøø ~€8v»OF´ {¯–4¥U¶¦UµüžZªP©èR £U°3ËÏÞÒË–émÇô²ejµ2¿@"«lT¶ *Úe­Ý¼¢&~¯\A"‚YÓ}ß›ãçäh¡×#¾ åàÁƒ&Lؾ}ûG}„wœ±¥¾¾~æÌ™x§LLL‚‚‚222V¬Xw ¿ 0b±øï¿ÿÞºu«VgÙ™›<éõd¤B¨G*/lä4ò ›x…M¼åÍ |‘\©BQÉD+S‹A³2¥™Rø}è•)yb _$ã‹¥R…!D!-ló‰žvÏMõrb;³Ìé†tIíããóÅ_¼üòË ,Ç;ÎXaÌ M\.öƒƒ"À$&&ŠD¢'žxbȯ`F£Lô´›èi§iQaXs·¸¦SØÑ#iHZ…âŽI¯L)‘+5Ó)$ ™N!Ù˜Ñí™&væ&¶ætw–¹£…éèÜÙ?¢6lØpâĉõë×ߺu FG{{»T*…"`Ôp¹Ü½{÷Êårø E€øë¯¿bccíìì~è##Ζ gK†_Ó°„_~ù%88xçÎ|ðÞqÆX$`”q8‰DRPP†w §ôtß9 !‰Îž=»téR¼ƒ!­[·nÙ²¥¨¨ï,cB}}=@€ž€Qãïïoaa«€A@ ïe2#dóæÍgýúõJ¥ï,Ư¾¾ÞÚÚšN×nÁ 0dD"1""¦€A@ ïŽ;6mÚ4}¹ÏÞȉğ~ú)77÷—_~Á;‹ñkhh€±€QÆår¡' нÖÛÛ c#-00ðý÷ß÷Ýw›ššðÎbäàÖ€ÑÇápJJJºººðôz-11±··Š€‘öÎ;ï8::¾ûî»x1rõõõPŒ2.—‹aØíÛ·ñôzíĉ'N´··Ç;ˆ‘£Ñh»wï>pà@RRÞYŒYcc£³³3Þ)Æ777E€þR(00jfÏž½xñâÍ›7Ëår¼³­¦¦&'''¼SŒ9°dú+99™Ïç?öØcx+¾ù曚ššï¿ÿï Æ©»»»··×ÑÑï c‡ÃIOOÇ;ÐSPè¯sçÎùùùyzzâd¬puu}ë­·>ûì³ööv¼³¡ææf„£Ëå¶µµÕÖÖjZÚÛÛÅb1Ž‘€þ€"@;wnÁ‚x§[Þyçssó-[¶àÄA€—ððp2™¼oß¾]»v=ñÄÎÎÎvvvmmmxçz– ÖSååå%%%Ð5=ÊètúöíÛ׬Y³aÆÀÀ@¼ã•ææf*• +^Œ•JURR’™™™‘‘‘””¤T*?úè# …¢P(0 #‘H°`Pƒ"@O%$$XXXL:ï cÎÊ•+¿úê«?üðøñãxg1*ÍÍÍööö‚Áo=e>ÿüó÷ߟB¡™L¦nÔLzupp “áÍ Ãzëܹs3g΄½¿F@ضmÛ‰'RRRðÎbTš››a,`Ô¼öÚk*•JSô3€úH$ݸqcîܹx£fÏž=kÖ¬7ß|Ã0¼³(FNÿã?T*ÕýO‘Éd__ßÑôúèÆR©tÞ¼yx»¾øâ‹[·n»ÿþääd†Ã‘ÛU¼¢f^IKWU»Pª¸;c€Å Y™ÒX š… õžÓ;E¥ S—<‘´Gzwb+Sš§­ù8GÖ8'«VËÅŠ1ªß(ôKZZš»»»““ÞA@ŸÇÜÃÃc÷îÝß}÷ÞY U[[ŒàE"W¦V¶¤T´(£ž@©©_g4ïæ]aÛ˜‡¸°–„²½l™ÞvL/[¦³¥Þr¥ª¦SXÙ.¨h”·u5ñÏÕµ %!+Æo‡I^öÓ|Cœ­a³=E€~ÉÈȘ8q"Þ)À¿H¤ 6lÙ²eëÖ­xÇ1Hííí¶¶¶x§[êx= …u õWKER…=Ód²—_̲5«žxüɸ™f´aíKB!}ì,|ì,и¾ÆVAoN}GZekryË»Ç3Å2…“¥é¼qnó‚\gº˜Óa'}E€Á0,##ãƒ>À;¸×sÏ=÷ÙgŸýñÇ/¿ü2ÞY R{{{XXÞ)Æ„šNᱬêcÙU™5m *%ÚÏqÇî¬@g?{K„`W¥R ³x{¦ÉÜq®sǹ"„äJUFuÛÅ↋Š{o–RHĹã\—‡{Æ…¸1é÷Ž5A G*++;;;¡'@YYY­Zµê»ï¾Û¼y3Ü^5Ð0Ò$rå±ìª_“K’+š-L¨‹C=>Ž ŸáïL%ÿëוÉdò""©‚'–töHy"© Ãøb©ºB"šÑ(42‰Å Y›ÑX¦ô{^ö~qŠ·Ão‡ÏEðDÒ“¹5G²*ŸÙ“D&–ý?{÷×ÔÕÿüÜ ²$ao{« "Š€Qp·ŽVmµÕÖíOŸúÔÖ§vXŸ>]ÚZëÀ½÷EAd#²÷È"!dçþþˆ¿G- šÜäæ¼_}õe÷†/„ä~î9çž;‚»<1$1À Ž˜ÌÈÍ›7mll†Žu!Ðc¼ùæ›[·n=þüäÉ“±®ÅòÀ`<õ|ÉK·ß¨Ë•iÞGWMžæ5àAZ U6ñŠšù÷;Ä5vcƒ²lLð²1Á¼ùÞüšß®U$}s<Ø…µ*9ì¥1! < a þöÍH^^Þ°aýádÂÃÓ’’~üñGž”Z­ …0ë?{„ߣi U¨·äTüûLQ¯RýöÄÈ5“"-kæàW_}õûï¿WWWc]ÈÁ`.nܸ‘P]] Ï2ÍÙ¿ÿýï 64773pE”ÁºtéÒ„ x<žƒƒÖµX0T±îdÁOWÊ#=8ŸOMò~t±\¹ófõOÙåe-“aëËesýÎN£9xZµZÜÜÜ]SÓÝØ Ñh¦Fx¯:%Ü‹Hx¸ž^¥ú—ìòŸ)BðEÆÈec‚ 2oÐÒC0‡Ëåb]ÔŸ+V¬[·n×®]+V¬Àº‹ÑÕÕE"‘Øl6Ö…X*-Šþ|µü³c6$–Åã^ˆzôøx¯CôÝ…’7«Õ(Êârƒ§±uuÅêØ¯G ‘X¾¾,__­J-j¨Ï­ª<õß3n,Û7RÂ^I cÑûÎøé6¤5£^ò¯“w^ËÊùéJùó]1,ÞJÀ`. FŒñèdȬ°ÙìçŸ~óæÍË—/‡/Ö uuuq8xiåÐ7 –ïȾÛÌ{{BÔÇiÃ]r'§º}ÃÙâS% tËiÔ(N@‘lvÝé2‰À PHļÊÊœ*úüdá+‰!k&FNf´£Úlœ¿|lè[ûr“¾=öòØÏŦÃÛ|[š‹ÂÂB¸šŠEX¹reYYÙ7°.ÄbÀë‡F¡Ö|xøVì—‡|=dî\§Ð03L†(L;‘q »$Œù£ Éç칿]¨înäbjõÔ]/?z·!ì³ýîÔbU­5€!À,Èåò²²2¸B€Eˆ‰‰‰‹‹Û²e Ö…X † ²]4zÃÑÍ—J¿ž=êú{îï–´R7Ÿžñß³÷”Ä ôé>©Sl]-©ç!ƒfÏñ›xªª+ìóýkößÔ¯M¤óüÈ€òÏ禆yÎýõ²íWõ·,‚ž-ÌBii©Z­†=–béÒ¥û÷ï‹Åo Áðä¶\«ŒYˆ@w>™õÖ„HÃit]ù«»r†}qð6_<}ºÿ´t[77 K}à2¾{˜_oVs?Þûß+ej­V¿ƒº}iòW&-ªY¨ ‡aµxC€Y(,,d2™X ÊóÏ?¢èÞ½{±.Ä2À0x2•úÅmW^Ýuíñ7ÞÏ4\rEÁ–k•þŸîÙQØà“’â?}†åþ !‚cHHðÜù´à·öߌZw(·¦ÃpƒÙ#üŠÿ1Ç‹m;æë£[s*±ª¯`0 ………ÑÑÑp攥°··Ÿ5kÖüu!–†€AªhøâйòæËkÓ¿šG&ö} Ôñ$ã7|uW#(,xî|ŽÀ×´T™ì>2.dîÜ6}ìÆc«²rºeJýW=XŒóoMû÷¬Q+wå,üýR¯Ra©8:fáÎ;p,À²,[¶ìæÍ›åååXb`Œk÷ÛÇ}sŒF&徟1.ðNñ·æT†~àO<3ÓcT„Û«º(L;ÿ©i>ÉIÛnÖ†~àÚývý—¼9!âðÊÔS¥¿?Ù)‘aX'žÀ€=µZ]\\ gZ–äädØ0 F#`èߎ›÷'m:™ì~ýý~ŽL}{—Džþßs+v]cEFÌ̤;:bX¤É8ÍÛËä$wüŸ' 4Ú¾íÒ£¼o8‹/•úêHY«Ã"q†ìÝ»wO&“Á`YyñÅwìØ¡RÁIËý …†€~|v<ÿÅ?/¿5!rïò‰4rßYþµûíáë\®çMŸîƒ VôqM¦Ñ¸“§xŒ½þôÝäïN´‹{õ_ p¶Ë}?ËÃóõÑ -‰VôWe¶ŠŠŠlllBCC±.z2K—.åóùÇǺ³ÖÙÙ €!à±P¼½ïÆúS…¿,LÜ0+N¿úŠ‚ï/”¤|wBÍq š5ÛÖÅ’.ÿ{fà”‘y§CýÅ¡œê¾¡õü[Ó¦„{¥ÿxæxq†5â Ø+)) µ±1ë%> GyzzNœ8Žô¯«« Àð8j­vÑ—~É.?²ròŠÄ¾s¥Z»hÛ¥µnºŒÁ4™hÝŸ 4‡À™3Uv)ß0¼4€B"f½.$P¸iéd:ÃòÌÓÝ›6íDysúOgeªK!øiÁØY#|3~:[Ú*À¶B‹CÆJJJ †¯¯/Ö…@C4jÔ(¸„ðßpB€ÞÁ;u¯í¾þíÜøÅñúƪŽîÄoNȨ nÚ4"Þ6w ggÿié×j»Ò<'WitÙ¾$e\ [ê¦S ül+´,0`¬¬¬,,, .lÑæÎ»gÏEÞÔú…B6›uf¡ ÷⟗— ~kB¤¾±¼M8úëc*[{nÚ4+¿`ð莎Üôôëõ¼´ÏèûˆdûÒdÝ&óç³ð–ƒƒ=ƒ³q`þüùyyyXbŽD" €.‰|Ö/çFs]~Z0Vߨ"’¦n>­¢Ò}'¥âx1`c ±9~“'çÔt.üý²öÿó7›N9ùúÔ‘tÙö«0“ ƒ!†  GK(²X¬·Ã5¥Z›ñÓYaÿŠIúÛõ(TSÿsV¨!r§ÂQ€¡`¸¸ø¥N>VÜðξüíçÈ<²ròÑ¢ú/NÁi:ƒC–x<^GG 80oÞ¼½{÷j4¬ 1;p8ðÉÑÛw›øûVLdÑtø«µÚÌ_ÎßHýÓÒH4*¶åY.¦‡»OÊøMK6],Ñ7&ø»¬ÏˆûüDÁ¥ÊV k³0`éÞ½{¸`0<÷Üsmmm999Xbv`8WÞüÍù¢ŸŒîÕw•ć‡o_¹×æ3q’ “ÙϾЀØ\®ëˆïÈ»|¯ï¿vRÔÌa~‹·]âKåÖf`ÀRee%N÷ö†«‚X¼¨¨(8"ð™L¦P(¬9´‹{ýqiñ¨ % AúÆ?s«¾9Wä”dëj•7xÖÜcbØ™?Ÿ¯éëZl[’İ!/úý2œÐ?°TUU/ À‡ùóçïß¿_­Vc]ˆ …kž°jwLúa~‚¾¥¬U¸*ëºSX' ÃÂpÆsÌ •>gËE…úÁœ-…¼eñ¸óÍäVö¿¯•ƒ‡,UUU ¼d ž{î9>ŸéÒ%¬ 1#"‘`µ=û jÜ­×]·¦k‘«4s·\´as¼F'ô¿/ôDˆd²ojjy[÷‡‡oé“‚ÜÞ™½vÿÍVQo?ûZ9°tïÞ½àà`¬«€ž .—G éz¬3tIä«vç¬J Or×7®9p£V õ™8!ÂÏÞgŒjoï™4nÓÅ’Å}7X7#ÖƒÅX¾#ÃÂÌüCÄŒZ­®©©=x2{öìãÇkµÚ7µÖ>>z‹L$|‘1Rßr¡¢å—«åî£È †…áÛËár_ÞyM UèZlH„ÿ<7ætYã±¢lk3[0`¦¡¡A©Tž<ÉÌÌìêêÊÍÍźs! ©T*FúS»]ßõ{νæ'èzª¥es¸\N``ÿûBOÃkl¢Xƒ®9pCß2>Äý…ø 7÷æê׆ Á€Ýõ0àIHHH``àÉ“'±.Ä\ˆD"+œ¨EÑWw]K óœÓw‡ûwæñä*ϱcûÙzzD Å#qÜöÜ*ÃSÿ³ãE2ņ3w1,ÌlÁ€™ªª*ggg+üˆÄ·iÓ¦8që*Ì…u.¸3ï~I‹à»¹£õ-yu¿fW¸ÄÆ‘(p] £³÷òfûú¬Þ{C['&õÓi#¾>[ï-ô(0/ À¥ôôôÒÒÒºº:¬ 1 V¸RB­ùDZüec‚Cݤ«²r™..ŽÁ!ØÖf=<ÇŒi÷~s®XßòZr¸;‹þ¯“p-á‡Á€™êêê@8:ˆ;ãÆc±XpD@Ç ïôóÕò.‰üóé±ú–m¹÷Ššx^‰‰Á°.ëbðu³þÔ]ý©?…Dü"cäŸ7îU´‰°­ÍÜÀ€™ššš¸ZîÉäI“&Ákë ÈUëO¾–îb÷`.d¯RýÑÑ|‡àª5ýÌsD‰Aÿôx¾¾e^,7ÜýÏùýìe…`À†J¥jllär¹o Yšôôô+W®H$¬ Ážµ…€ß®Uô*Õk'Eé[þ{¥L(S¹Œíg/ÈD¢K\Ü®¼ûåmÂ-òá”á êô-€!+jµÚßßëB goÚ´ijµúÂ… X‚=«š¨Òh7],Yž¢ïö*þuªÐ1*ŠD…ó1Àöã2œ>>N V6'`÷­ê±ìIÑú–Ÿ®”+µˆsx†UY9§a#ŽÕ5óu ònjôŽ›÷›„ð2`ÀFmm-‹ÅrppÀºÈ(ÒÓÓOž<‰Zýýˬj8`ó¥Ò™Ã}=ÙV”©Ôß^,qˆˆ$Rl°-ÌšÙûx3œ¾4X!`á¨Ýæ×ì «2+0`£®®ÎÏÏë* c™:uj{{{QQÖ…`I¥RõôôXI¸QÛq§‘÷ö„¾Ù[s*{çˆp «‚ŽÑÑ j«;Üe˜F&­L Ûr­R©†Ë{CVjkká„‹ŠŠruu=þ<Ö…`Iwm°s IDAT A+™ðóÕòÇx®³î¡F‹n<_ "R(ر|ýhLæwûæ¼:.L U*„‹yCVjkká„C$99ùòåËX‚%ë¹{@ª8PP·|l¨¾å\ys³@â»°‡ ;4lûûRŃÝìéS#¼¶æTb[˜™€!5550à[JJʵk×T*Ö…`F×` !`_A ‚€çFöõíý|µÂÞÝʶŠ^óç¬Ôhwߪַ,|ù^+\EÀ€ ‘H$‰àœ|?~|OOO~¾õ®L¢ë °†á€7«g÷µ§=˜Ø*ê=UÚȆ‹› …bïë÷‹Á©z”·£-Õ0X-0P__ðõõŸȘ|||.]º„u!˜‹ÅÉdb]ˆq5ð{rkÛçÇöudÝ®&ÚX~¾˜Õ=‚t§¾ó^ǃ5ƒIÂÌá¾{ók°­ÊÀ€††A¼½½±.2®¤¤$kž ‘H ‚à|ÅüwjÙtÊ”p/}ËŸ7«íýü D†UA±óð Ù2 OýçÇú5óáê0` ©©ÉÉɉ û”””ëׯËår¬ Á†D"Á}7àXQCZ„7™øà³´ª£»´™ÇæÂkÌ ‚Øùqÿ¼Ùƺ91©'Š1,ÊÀ€¦¦&//¯·ƒ,Ü„ äry^^Ö…`C"‘ØÙÙa]…q‰z•¹5éQ}½zîÔRé4[wW «‚‹Åå6òÄÅÍÝC"™î}ª†ÈäáX€5ðòòò÷÷·Úkè ¸PÙ H óÔ·.j´õòAøÑjvl]htú‰’}ËäpÏÜšŽn™ê0ÿR1ÐØØ{¬Äøñã­vn X,Æ}8_ÞããȦ?X¨K"/¨ï´‡ßtJdU¢±}Ãÿ—ïµÚ:9Éd «‚úÁôpGQSÝ®oI t½v¿½Ÿ]p†SkmmÕh4°'ÀJp¹\GGG뜈ûp£¶Èh®‹¾åRU;ÍÍ Ã’ þ‘(T&‡}­ºïÔ?Áߥ°‰×«TcX¶`0µÆÆF VA¸¸¸[·na]pòê:C\Y,úƒ…y=òÚN‘­‹Kÿ{AØ¢8»^½ß¡8šë¢Òh x–„-L­¹¹™D"¹ÁÓ«{péN#o¤¯“þá­úNÃÙ»Š 1\ï6ñjÓ™I»ÓCd*---®®®D"ëB 5jTmm-guŸ2¸EM‚HŽþaAagG‚‹€™7†“³J­)kí[(0ÒƒSÜÂǰ$lÁ`jmmmîîîXW™N\\À Gð:%²vqo”g_(jØp8ýì™н=‰DÒ/ˆòä>´60˜Zkk+ °*ÇßßßÚFP•J¥8º5çÃÝ zšøŽvAƒ‚ ƒÃ*ié;ꇻ³+Ú…(ŠaQX‚!ÀÔZ[[aO€µ5j”µ…€žž­V‹ãeƒkºÄ¶²;‹®{¨Tkùb›mUÐ`ìÙe÷ p²—*Ôíâ^ K ¦{¬P\\ÜíÛ·Qk:×H$÷4ð{|lû $Z-Jaâ6ôà ÅÎî~—DÿÐ× ¨çKþ~<ƒ!ÀÔžfN‚ OtcÖ'ÝÞ†Pƒ%þ˜ý‹55VtóòÁ‡ }¹ëxÝÁCGw±±³ýû=0P‹Äö÷»zhƒþ£LØ0™ÍB‰>“{²d"†ÈÄbqOOì À–é"Æ #‰Vµn ùôéånJ½Ø}‡üFA™L&Qà¥À†i«Ti:$úÿ‰ÄEoH±­ +0˜T[[Î °6t:=  ¤¤ëBLÇ|B€‘tõÈ\ìhú‡mݽT[:†õ ML>“oE£T:6t ­»o€3“Æë‘cW–`0©ÖÖVC€UŠˆˆ(--ź ÓÁ}àõÈl)ú‡ü\!ÀRè^)㾃 Cd ­­­d2ÙÉÉiàM¨««ËÌÌ´µµutt\¹reoïc&¯îܹ399™ÅbQ(”€€€÷Þ{¯»»ûïž0''gñâÅžžžd2ÙÁÁ!55õܹsº/]ºt A777™Lf¸‹B¡ðôôDäâÅ‹ƒùŽƒ©ÙØ?fÿÛë{†CþFƒg…!ÀÆÆÆÆÆæ¡v|¼Ü( R…£ï¨Ï둳 è)º~7™UGìܳY×ò¤cö‚S;«V$ßMfÝM)Í hÞüž¦§ï7¦h­«Y›Y˜h[4Á±ñ«•Z¹™Î·'ÚPßÓwoOG[*_j¥!€„uÖ¥££ÃÙÙy0#”|>ܸqÍÍÍ©TúË/¿tvvn€¢è¢E‹vïÞ­o©©©Ù¸qã©S§rss{iVbb¢þßàüùó.\8|øpFFÆøñãrssúé§µk×ê7ûí·ßZZZFŽ9a„¿ã€5›àǯå)w¤ˆˆˆšššÞÞ^:Ýò:‡à±+áæåîUªU-›nÐ UÌ;ˆóÎ׬ÍðÍûqÓŸx­ût‘àLßoLÑ\Óñ×FqΩàm¹D†º›_õò8eg3@+“vüE%àíØÐlô7°è6‚ +Âì 0©ÎÎNWW×·à믿nnnöññ¹råŠD"¹|ùr~~¾á¿ÿþûîÝ»=<<öíÛ×ÕÕÕÛÛ›››;räȲ²²/¿üò±Ï9uêÔÓ§O‹D"¥RÙÜÜüý÷ߣ(º~ýzÝW?ýôSÝ÷•JLQ(6l|øá‡ƒùŽÖl‚sÀíõ×顆öû|"Z­¶¢¢âéŸÊ"H$’G¥¸y¹u+ÏSH}‹KUjÑ|Ï©DWŽT¿=hk¼%{( ÞÑßgv“=¸öE_è~½7ä\FØHYmYû_:¶­ìl¶qó úíÊðlIЯ—{ËxûcˆH$ÉT}w¤’‰r•Ãz0C€Iuvvr,àØ±c€ÿüç?III¶¶¶ÉÉÉ?üðƒá[·ndeeÍ;×ÑÑ‘F£=zÏž=€C‡=ö9×®]ûÓO?…„„ÐétOOÏ·ß~ Ÿ­6eÊ”ØØØÎÎÎüQ×òÛo¿µ¶¶†††fffæ;X³ ~Ì!üZžrÇA  R©Ö3"ð؞ܼܺ`C"´h¢™~œ Nïª}.Õ;(d{=dÄО„wd+€»>‹=q.‰åH ÐQ£ý¾Ú^>ex¿ûæˆ$Ý–“ìõÎo ˆDý=„Òÿ<´*æ]q©³³Óyp7«««ÿÛŸ””d¸îà’’þÿtG–S__ÿèîÝ»÷ùçŸt½¹¼o$ì“O>ÉÌÌܸqãk¯½F"‘tÝï¿ÿ¾nübÀï8`Í&ø1Ÿtû§ßqH$RHHHYYÙÓ?•E‹Å†Ü¼ÜJµ<4ÁLï V÷Ù TŸààßsˆŒ¡jɪKU¯¤P€Š([ëŠÖ:€íð¾—9b€·?†"Áð¨oC´Þ`¦Ñ¯¤ûÀÒh4F«ÕjµZý^¥R=ºýºuëP}õÕWïÝ»'“ÉPíéyx lÆŒQQQ|>ÿ‡~Ðux{{/X°`hß“sÈEšà§‹ˆˆ°ž«‡v÷ Ky¹ÕZ-€ˆô}~j´(ÌnU„@”×W NîxªgÑE%­Õj€V ´Z jQëío<‚h´}gDDÂÿ<´*0˜TWW× ‡üüü×®]Ó·\½zÕpƒððpÀ­[·ÐÇyô uËÕmذ!((ˆJ¥ôþõùä“Oß~û­®àwÞ!“ɃüŽÖl‚s0Ûë:6Ôjõ“îø”¬ê©Tjkûðòy¸y¹u³”ƒSIÕjÜÜ/÷ bãׯwîÞ4ä'¡ú‡Bþº¥[Zà¡ÿw?@Oaß‹+¹3ÀÛCZÖpJ‡R£1|hU`0©Á÷̘1°zõê«W¯öôô\¹råÍ7ß4Ü`ÕªUºÍ¶nÝZ__/“É EUUÕ–-[}B///À×_-D"ÑþýûW¬Xñèf³gÏ  …mmmNNN/¿üòà¿ã€5›àÇÌöº¶ÿ~á'ýFCÚÒÒòh .=ö:ܼܺݠ€•DDµfÚŸÌ?ËïË,„HjúîíŽß íIœç¬Ô¼=ƒwd«²µ^«¡J…¼±ŠwxKå²kÜ @ãÆÕ’;Wµ½=’‚+Mß ðöǪýß ÖîXäYå@êééa2™'OžLKKpc>Ÿ?lØ0ÝÅT:³fÍÒMYÒ¿do¼ñÆþóŸÇî®ÛFw¤û÷Æß{ï=Ãm^xá…¿þúËð uvîܹxñbÀ_|ññÇ~©ÿï8˜šýcfû¥K—þù矶¸ãS*//¿{÷nttôÓ?›™›8qb``àÏ?ÿl؈›—[Ô«d¿ýç¹·Ò&…zêZƪaúLw0º5tgêÂóûê>^€j5¯åºäƒG7ðaÓÆ7:÷>þ7“ª»ùÏÓ]"¨Ã?Ktéá3˜ŠÝ»Ö§E½5!R÷pÍþ7k;sßÏÂS}õÕW¿ÿþ{uuõ3-Ðt¬4û`¢«« 0Èž‡ììì3f0 ‡³|ùò;ÒÛ¼yó… æÌ™ãááA&“i4Zxxøš5kîÞ½ûè®Y³fãÆ …Ëå~þùç¿ÿþûc¿u`` €Éd¾öÚkOôS³±ÌÁl¿iÓ¦•+WúøøèG:†öž”ŸŸ‚ µµµÏäÙÌœL&£Ñh5âæå¦Ù2eß©¿=¤5Ú̘g‚=ižß»±åÇÛ¶þkÏàõîæ Ÿ.°'Ì!;{ $2B£qÃ]® Û}@²wÚšÍ7ƒ@cì8Ž3—û­{ºYƤVª˜Ô¾¿™RC·±Òiò°'Àtòòòâãã¼½½±®¥?Ë–-Û¶mÛÚµk¿ùfˆ=‡ÐßñððX³fárLx5|øðiÓ¦}ñÅXb,Ì7¶ý0?aÙ˜`ÝÃ;³Ô÷p§ÜÉaÕhïü¾õȪԌh_]ËÜ_/`ïò‰Cx6Ø –®'`±R__òäIÀ²e˰®‡¸\®•ôôöö>Ú€'¶Ã…fT­ÜJ×µ8j…ðЪφ­Š•v€`‚ÏçÓétsþdÔ¯gœ––†m1¸d=!à±ÃxâÀ .>ÏaPÔ0XÝ+Åa®úl½!ö˜ŽP(d³ÙXW1*•:eÊ”-[¶`]>ùùùYIÀý]œ™´vqß r¼9¶½R©Ù^%RJz^ì¾KX;Ä2g;+ °'ÀtÌ?À "ÆÆårëëë5 ‘ˆó‹’qü™e­BýC_&ªE•R)¿wOÆ E˜Å ê'JäªN‰Ì×ÁJ_8Ø`:æ cãr¹J¥²¥¥ëBŒ EQ¹\Žïá_f=_¢èçÈ(Å’¿ß2J±Ä×±ïß €ÿ­ ¦CÄår¸ЭKïž_f‹Hª_/ÈÉ–F³!+ÄÝØV †R,vî»B=¯{ £ƒ!ruu¥P( Xb\½½½|‡';­å‰uDxrzl«‚C)äG{8èÞïìv±£ÙRÈýì‚c0˜ @psskkkúã’Éd|Dx°ÉDÂÝ&¾¾%ÆÓA-ä÷³ d4*¥TÒéÁÑ·Ümâórèg|ƒ!ÀtD"‹Åº c®®®XWa\ÖÐ@!ƒ\ìKZúNýÃÝÙ½!€“kÍ›\ (wï;+náGyÀì €®®®¸ï °†ˆp熀Q~Î ¹BÞ-°$h@=[š~€Z«­lExXï'3 ¦CpsskooǺ 㲆á@¬Ó­úNýÃa^T2©§ç/®¥ëíhO tùÿuÑ@Q“@®ÒÄú˜õB®FC€‰Èår¹\CäêêŠû`%=c\;IJû®  #}¥í8ë±l(ut$ú»ê®U·91©¡®ÖûÉ C€‰…B  ¸ããH·!]¯î;ê'¸ÈaO€“w‹d½²}ËõêŽx¿¾Ž+C€‰À鸹¹uwwë“x%“ɈD"…BxSKF&†{9æÖöõ§FxõˆºÝpµ3ÕÝÔhO§Æù>¸Ÿ;Š‚ÜÚöÑ\—þ÷Â7LDàÕ««+ßàþ‚z©až§K›ôËmÇs™4›î¦&L‹‚þ–´©yJ¸‘ðàÄ¿¨™ß*êî‰mUØ‚!ÀD`O¤ãææÀ÷ˆ€õ„€´H¯f¡T‰@âÞÓÜŒmUÐciUjI{{jhß!ÿti“›=}¸—#†Ua†‰DT*ÕJ>¡~899x<Ö…îï¤7ÂÛÑÅŽvª´Qß2w8·»¹YwÇzȬˆêªí£o9]Ö˜æiÍ &# áX P(T*U$ÂóÕä2™ÌJò.ARÃd"AT[]QÐãu×ÖŒñp´}pË`¾T~³¶sJ¸¶Ua†‹@z, ÷!ÀJzóbü¯×´7ð{tm)ä)žâ:œß#Êâh”Jqsós±\}Ë‚:Á°cÀ:Á`"0@zöööݸž@n=ÀÉáž,åPa¾eq\`wk‹RÚƒaUÐC55D€Ìæ§oÙ_P›áM·!aX•9€!ÀD`€ô¬!XÉp€L$L‹ô>x§/d óq°¥ñ*+1¬ zˆ¨²bþH.‹n£{Ø%‘_­j›=¯ÿ½¬ &"‰`€t¬a8ÀzB`ᨀÜÚöÊö¯)‰@X6:¨ûÞ=…w2 ½<ž¸‹÷ò˜}ËŽ¼*º )=ÒÚÇ &#‹™L&ÖU@f÷=r¹œJ¥b]…éLóòw²û5»Bß²$!H&•v76ö³d2¼Š ?'û±V FQðkvÅâø@ÅÚÇ &#•Jmmm±®2 , ß!@¡Pà~¹@C–&ÿyã^¯R­k qeM‹ôé*,Ķ0 ’ö ªª>˜¥¿0û~[UG÷ŠÄPLë20˜ˆT*µž©RPÿìííñ=`m!ðâè ¹ÚpfÀ»©QâÎNxSAÌu––²é”Gé[~Í®áíåÉÁ°*óC€‰H¥RƒuY°··‹ÅXWaDJ¥ÒÆÆë*LʃÅxn¤ÿ×g‹ôÓÆºEy9vcZ—µÓ(•‚ʊגB)$¢®¥¦K¼¯ fí¤(l 30˜ˆU]4õN§K¥R¬«0"+ì ¼›]Ö&8WÞ·f𗱂úziG'†UY¹ö¢"¼=1RßòÃÅRcžÁ‚V†=•JU(XWaDÖ¢<9‰nß_ì;õŸéëçÜQaUÖL-“ñKKÞK²§=è—ö*þ¼qïµäpû€¿S@QT&“ÁéP(¹ÏkË[g|0eØÙ²æë5}ó֥Ǜ›{ÚÚ0¬Êju1Ȥ×SÂõ-ß/! ¯ŒƒSûÀ` 2™L«ÕÂéP(|÷Xᜩ^)Áîï¼eØ2)̳õzŠj1,Ì É„ÂÎâÒ͈±£>øSì”Ⱦ¿XüÁ”aúŽÀ`º`8'Ò¡P(J¥Ç+ÉXmOàé#®×´_¨hÑ·ü0/¡WÔÍ«¼‡aUV¨ýV^+keR˜¾åû % òª¤ð~ö²B0˜‚.ÀžH‡J¥¢(ªT*±.ÄX¬9$¹§†y¾w0Oûÿ!/ÔµtLPWAFÛWÜ܈›› gÅ hôl¾TúqÚp¸@ÐC`0…ÞÞ^CôÿtHO P(Ö9 óÃü„ÒVÁÖœ¾{|•G#h[oåaX•õÐjÔm×s¦Gû¤Gyë×ì¿áïd÷Z2ìx ¦{ Cº€ãiJ¥Òj{!®¬UÉaŸÍï–=8õw´¥þºplWe…¸¥¥ÿ}¡§×v;Ÿ Tü¶(Qßr¾¢ùàºMóô ¦ç@†¬¡'ÀšCà“´*ö‹Swô-sFp§„{·]¿®U«1, ÷z»ººJKÿ=k¤«ÝƒÏ[•FûΛS#¼Æ‡¸c[›y‚!À`OdH×U®R©°.Ä(ÔjµV«µòàhKý~ÞèïΗäT÷].¸}I2U£l¾~ÃÂðM£R6^º0%ÜëÕq}ó¿8u§¶KòËÂÄ~v´f0˜‚T*%VusUh@x½:@7ÌaÍst^4!Äã忲å*®Å‰Iݱ4‰WuOPSƒmmxÕr=—¦Õl{1IßRØÄûòÔÝu3b½9ðþmC€)ôööÒh4ÃQþé®z°òžÿ<ŸÐ üëdß À”p¯G·^¿®H0, —÷«y÷«~]8Ɖùà6Ö*öÕ9ìÕãá|À¿C€)À[BÖC×C Ø…õíœÑÎܽXÙ7ðçcÃ]˜õgNkTðŠÁgFÚÕÙ˜}õýÉÃf ÷Ó7~täVi«`÷Kà"Áý€¿S€7€¬0´*9lF´Ï‹Û®ð¥æRÉÄ}Ë'ä²–œ€Ï!SS+äÍ—.&ø;ÿ+#Vßx¡¢å»ó%›æ%„º±0¬ÍüÁ` 0@Öö<ä×E‰-úÊÎkúI þNv{—ÔԶݹÓï®ÐÀP¦áÜ9;ºùDý—D¾tû•ô(ï—dž`[žùƒ!Àz{{a€¬œðg&íðÊÔãÅ _)Ô7N ÷úkirÛü®Šr k³t(ŠÖ_8Otg¯Mw±{0óZ¥Ñfþ|Ö–BÞ¹l<œˆ5 L¡··Î €¬ì xT<×ù«™qŸÍ?[Ö¬o\ðá”á-¹7à BCÖzë–¤¹åà+üìô¹u·‰¿oÅD&•Œam–†S€k§@ÖÎ x¬·'D¥Gy¿øçåz~ßu_dŒ|!> þÜÙž¶ö~ö…«ýÎÎ’â]/¥$õ­´/¿öÛóÅßÏéÁÁ°6 C€)(•J2fRèÝ x½dö<‚€¬—'ø92'|w²K"×7nY4.3Ú§îìig'¶Z–ŽââÖ‚ü­‹ÇÍáê/V¶,úãÒ;“¢W$†bX›e!ÀT*<1‚ôtkâ5Â9‡nC:ðÊ$¥FóüÖ‹*V×H$ »–¥¤†¸Õž:%iköBKÑVXØ’wsóü1K‚õµ<ñó[/N‹ôþjf†µYLö@†ð}®ŒïŸî)y°§VOÍoèZôÇ%öÁÕd"áÈÊÔçb}kNÖÕa[¡¹CѦœœŽ‚‚ËÆ¿žÒ·P«¨7uÓ)'»]/‡w z"0˜ì € éΕñú'çô/Òƒsî­´Ó¥Mó·\Ðç"ùcqÒ‚¸€†Kù÷«°­Ðl¡ZmCöU~eåŸK’ÄèÛÛº{“¾=Æ¢Ûœ}3nC°BKC€)ÀžÈ¾Ï•uíxñðLÄù:|uÒ‰âÆÕ{®ë í/&¿™Ñpå \?àQ•²îÌ™žÚÚÃ+'-¨oHé?žœx}ŠFÏ'C“)¨T* =|÷¨Õj ~° `R¨çÞæÿvQ¡Öü¶hœ®AÀ·sã½9¶oï¿¡”ˆ½Æ&ˆD¬+5 ‰¤áüY²¼÷ÊÚôQ~Îúö±,õ‡“¹êòšéú{COö˜‚R©Äë'>4 …‚H$âõH CÀ eDûž{+í@A]æÏgõw¼9!âÀ+{ëêjSJ{0¬ÐLˆ›šï>äNBóÞÏ4LÕâQäæ™>ð&CC€)ÀžÈ¾C! ƒ7.ÐíôSsªÛgþ|N"WéÛg ÷Ëÿh¦ AU}ø¸¥¹ŸgÀ7EÛ ïÔœ=é™ÿQf€sߊ@%-‚ñßpfÒ.¼=Í™ ïÒ>t0˜¾?ô¡'…￞H‚¿Kö;3ÊZ…‰5 ¥úöP7VÁG3g„{VŸ:Õró&ªÑôó$¸¤”öÔž<ÑUXøýÜÑ{^ž`Ké;:[Ö<öëcì‹o§;0¨‰0˜ì € ) l IDAT ½HÎÍ2Äo8’ßÐ¥o·¥÷¼<~ÇÒñ=U•5ÇŽÈø| ‹41Áýꪃ=EþG3ßaø¥Ÿ¯–§ÿxfþHî±×&Ã…Ÿ ¦Cdß÷’P«ÕD8í ¹³èÙïÌîí¸ñØï×+ ¿´pT@é?æD±)•‡7ß¼©U©±*Ò4ÝÝ5§N6\½üú¸à‚f®þ+S©—n¿²zÏõ/2c[4NÏ@èiÀÀn øîþ…ž”T*µµÅí<&Ø04L*ùèªÉëNÜY¾#;¯®sóü1Tòƒ,åã`{uMúo×*ÖÈ»W_ë:*žíÇíÿÙ,‘V­n/ºÛUTÄu´;ýnF<×Ùð«µ<ñœ_.4$'_Ÿ:9Ü«"ñ¾WMö@†¤R)Žo-­Ñh`‚üszLŒã Û.ߨéÜõÒø(ÏçÁ^šéµzOîÑóØîîn£hx¹G µ5yy…üÃÉѧ §þ§3鯛U«³rýìò?šåçÈĪL\‚Ý)¦{ C°'êÇô(ŸÂOfÛÓlâ¾:üý…­~9!¼Ø¶GV¦^|;Ý‘W>ØpåŠB"éç©,‚¤¥åþ±#õ—.¦‡¸Üû|Þº±† @Ô«|~ëÅ%^Y:&(÷ý ˜ž9ø^5Øêéé=P?|˜×Þ±ùRé{‡nþu³jëâ¤GýWLJ¸}2û¯›Uÿ¶{–Ox=%|ÍþáÿÜ¿0.ðÓi# —ÑLñ˜â!*vݺ¿#¯:ÿÜ ÅÎ××ÎÛÇÎÓ`òªJ*ínl”4Ô‹š[ÈÂÔH¯%™©iÞäÇå’³eÍÿ<‘«®kq|à—™qî,Ü.¤anà{ÕèPÀ;«Bz"‘ÈÎÎnàí,\,ÈxƸæ}0óPaÝgÇóC?Û·pTÀ»©ÑáîlÃm8 ÊꔈÕ)‚žýµ{ïÔ\¨"vînt7O†« ÃÑÉxÝ…¢§££§½]ÞÒÜÍãQÉäIaó'%Oòyìê~Z=YÒ¸áÌݵѾw?m¸:d0˜ žH$b³Ùog™`O€Q!˜=ÂoæpßÝ·ª×Ÿ*Œ\·r˜×ÚIQC=ÚÒ›c»vRÔÚIQ|©ülYóÉÒÆË÷JïåÝ$‘ˆ G'6‡ÆaS9lª=‹<Ôõ+Q­VÙÓ# eB¡L(Pó¡A@ˆ{r´ÇÔˆ¸qn]ñ¯'WivܼÿÝ…â{¢´ï¼fŽôuZÐÓ€ïU£ƒ=!­V+‹qà%‚&@@E£ Ì©nÿ÷Ù»“6ôd3^²*9ìÑ[ê90¨ âÄš…Òë5í·êºò›øw kĽ ‘DdØ1‰L;‚ •D¥©…úèG–V£Q+ä¹B-W ò^¥DÜÛ#Eµ(ÀÃ9ÆÓ!6„ÏuŽç:ÛQûý,lâýrµbÏí•F»<1ääê)\GÜvŒ™?ø^5:Ô`­êîîÖjµ8°'À”Æ¸Ž ˜’[ÓñûõÊï.}¶hNŒßüXÿI¡ž6¤Çôù{²ócýçÇúë6 {îwˆëù’:ž¤ž/áõÈ»zD¼v…HªÐ¢¨D¦ÐmF"h6d‘Í 8ÚRœm©.îv¾~ŽL?»P7–=mà9O|©üpaýμûÙ÷Û|8Ì·'F.ìÍÁí YKß«&{ ¡P€!z†ü]ü]6Ïs¨°î¿ûOÏ8sÕÞÝ/s˜oÆ0Ÿ”`÷~Î˽ض^lã†=gËšÖ]¬l¡Û2‡ù~–“ä?Í|¯ì € éB‹ÅpK CVÒâøÀŸ½>‰DN›>gÏíší?Wd´¿sj˜ç¸@·‘¾N¦¹è®K"Ï­m¿TÙz®¼¹²]D·!MðÊzy´Hoý]‘ 3ß«Fç@†`Od</^ܹsçsã#ÞÑ%‘Ÿ)k:UÚ¸éBé§GómH„o§Ñ\—(ON¤'Ìý¬É©¢¸…_Ú",lâåÖtT¶‹A.öS½6ÍKH rƒÇ~³ß«&C¤#‰‚½ýcVJÁµZM¥ÂE^±±ÿ~6cÆ ÝC'&uq|àâø@íµ9ÕígË›þs¹T¥Ñ ×ÑÎßÉ.ÀÙÎßÉ΃Åà0(l:…àØÓl¢é×hQ±\©Ñ¢©BØ«Ðý¿ž/©éWwŠïwv·u÷˜Tr„;gj„×úÌ‘ þ.®vðZ C€ÑÁáÈP(´³³#°_ÇÍH`O†²²²¦OŸNä’?anì07öKcBJµ¶²]TÖ&¨êènà÷T´‰Î–5·vK¥ õ ¿‘ƒê΢û8ØFyrÒ£¼C]Ùáîl_&<Ù±8ð½j"°'Ò …8 p± ìÔ××߸qãƒ>pK!Ê“åùð²<2•ºK"ï˺eJÝÙ¿®]×+@@'&ÕÑ–êĤ’ð›b­ Fç@†¬!ÀžLìÙ³‡ÃáL™2eÈÏ@#“¼9¶ð²=«ÓœÑÁáȾ— p± ìdeeÍš5 Þ« z"0˜ì €t„B!ޝh4Ïx0[eeeÅÅÅÏ?ÿ<Ö…@¾W@†p?€¢( ¦·gϤ¤$¬ , |¯€ á>hµZyM EѬ¬¬yóæÁø=)øc"ðcÒÁ}@Qþµ›ØíÛ·kjjàX40ì € á~N0½¬¬¬   ‘#Gb]dyà{ÕDà¹@Q´»»ß=p8ÀÄ4ÍÞ½{çÏŸu!E‚WòÅ+¯¼¢[" V«ÝÜÜ>úè£õë×ëZÈdòÁƒíìà-´­ŽD"Q«Õø°'ÀÄ®^½ÚÖÖ¶`Á¬ , Ʋÿ~Çmmmú9&ëÔÕÕprrº#‚=&–••‚u!E‚Ý(–.]úw_"‘H‹/6e1ùàñx¬ 1"81Д ÅÁƒá”@hÈ`0Šøøx??¿Ç~I«ÕÎ;×Äõ@f‚Ïç±.Ĉàp€)={V$Á±hÈà{ÕX–,Yòèâ©!!!ÁÕÕ“’ Ìñx<Æ`0°.Ĉàp€)eee%$$xyya]d©`0–^xA£Ñ<Ôˆ 츳f<ßÝö˜POOϱcÇàG ô4à{ÕX|}}GŽùè§! °f|>÷!ö˜ÌñãÇ•Jå¼yó°.²`0ѲeË „±cÇâ{f8Ô?‡ïYö˜PVVÖ„ àG ô4à{ÕˆæÍ›G$õáXd ð'À4ø|þ™3gàG ô”`0"6›––f8=pöìÙÖaÎB¼DÐ4:D"‘fΜ‰u!eƒ!À¸–,Y¢V«D"1)) ÷¨|>߆`0¬¬¬´´4¸ìô”`0®´´4{{{Ý¿aÇd =Z­Î 0¶–––«W¯ÂèéÁ÷ªqÙØØÌŸ?_wb”‘‘u9–Pµ†«`O€ ìÛ·ÉdN›6 ëB ‹C€Ñ-Y²EÑ””8‰×ʉD"µZûáØ`YYYT*ëB ‹o ô,ÉUšê®îš.qM—¸¶KÒ.îö*=rË)ñæ¼½ý¡í ÂfØpèT6ÆM§x±mýìüì¸NL_&žNá‹5¬ `O€ñÝ¿ÿöíÛë֭ú`x*¢^enmûíú®ÒaI‹ º«[£E.v4';#ÐÙžíëì6ëùÔ9 é¶Ì‡v×hQT!ìUèþ¾¢ù—l±D®0(¤PWv”''ÂÏuŽñv²!Á³+˦»{ ÐSÚ³g‹‹Ëĉ±.ž˜D®:_Ñ|®¼9§º½¢M¤EQ/¶m”'gæpß(ON¨+ÛßÉŽI%î"Ÿ5øŽ»±ì~gwY«°¸…_Ú"<Âýo?²»eÊË÷Z¯Ýo¿RÝQÜÜ¥Vk)T*Ã&³í†81™6vv&“0èÉ;j¹\!+Å…DrW(Ì¿Ó"½X¦V«™4J<×e\€sr{<×™ôHG«;‹þIÚˆ¦?SÖ´éBéŒÿž sc¿79zᨀG7†0$ Ùl6ÖU@,+++<<|ذaXá  êU~w¡xÓÅ*™øÆøˆUIáNÌÇOå+kî/¨=]Þ\Pß…¢€éäHqqñN‰²uv!3žj–‰J%Q© 'g} Š¢ QwOGûööÜ+UŸͧSÈãƒÝÓ"¼æŒà>T!AÒ"¼Ó"¼‹šùßž/^¾#{ý©ÂNyn¤?\oÀLooo¬«0:APź R«Õûöí[½z5Ö…@¸bí!@®Òüp©äßgŠHDä“´¯%‡3(ù´ˆ¤»oUo¿Y]Ö§P)¶ž^Þ)áöž^D Åxµ!Be³¨l–cH@Ñ-înlÈij<½7÷½¹C= xtJ`´§Ã_KS>Ÿ»þTá’?¯|uúî†YqÓ"ñì1B¡0::ë*Œ†#¹xñ"Ç[°`Ö…@¸bÕ!àÀÚ÷æñ{L¶z|¸-åáËí”jíñ↭×ï+o¢Òh ßÀañLw7Á ›boçé©Q(E ·ëë.lÏ~eW΂8ÿ—ÆÇù:nìçÈÜú¸҆ýóxÁôÿž™êùÝÜÑáî°/KÀ†`0’¬¬¬˜˜¬ pÅJC@e»h宜ìûmK‚ÖgŽ|ôz?TñKvù÷ËR9ÛÇ›;y²§—™ÌÈ%Rl5J¥ ¦zoå½ß²+¢½?Hžãg8€ëh÷×Ò”×’Ãߨ“;ì_W%‡}‘1.-€¡Ph a0™LvøðáÏ>û ëB ¼±º Pk6œ¹ûÕé»áîì¼3c}¾©O«¨wÃÙ»[r*Q‰F¦™hI€'E´±q s ëåóš‹Kþ~yí¡[¦F-O ¡ú.gåç|ヌí7ªÞ=w¸°þÇçÇ̈öÁ°lë¤Õj»»»aO44§N’J¥ðºè™³®PØÄ[ôûå:ždÝŒØ5“"š<ß!–m8s÷ç«D*Õ)&Î1$„`!+ðÐ}SRÜcc;ŠKÞ>÷噢Ϧ _š¬_r€€ K‚§Ez¿¹77ã§³ób¹¿,LdÓ8¡zˆX,Öh4°'𬬬ÄÄD777¬ ðÆZ.!CQðíùâø GØtJñ?æ¼79Ú0ô*ÕëNÜñû8kË­:—øøùÏ9GFXJгa2½Æ$„=÷œÖËïõ½7ÿ±ïà:à œ™´¬—'mJvU{ôºƒÙ÷Û°*Õ ì €† »»ûäÉ“°2 ;Î M—D¾èK—*[?›>âÃ)à テ¢`÷­êwÝâË•.1#‘Á­ h¶ÈtºçèÑ.âÛnçÏýíBB€ëó†yõÝÃ>=Ê»è³_þ+{üw'>NþYz ¼†Ð„B!ö@CpôèQ­V;wî\¬ pÿ! ¿¡kö/ç‰äúû3šBßÀïyyGö¥{-Ž!!¡±#IOr›3G¦Ñ½Çs +»‘ûåáwS£>Kѯ{è̤]5ù—ìò5ûoÜ®ïÚõÒx84`l°'²¬¬¬ÔÔTkøãLϲÏzôgnUâÆcáîìüf&?])û|ÿÍÎÞ Œ ¯±‰xJzt'Gÿé3<ÇŽýîJyĿިíÐ AÀʤ°kïÎ(kÆ®?\ÔÌǰNk  ‰D¢½½=Ö… ÏVGGÇ… àXd$¸ Z}÷àÍe]yorô‰×§p}gº­¢ÞÔÍ§ÞØ—ËŠˆš9Ëp‘>B€cHHÈœy":kìÆcŸ½­Òhõ_Œõq*øx–¿“ÝØ¯/nÀ°LÜ,ËL®25*ž­ƒR(”ŒŒ ¬ ð Ÿ! [¦œºùôOWʽšúùôXÃ1ïÃ…õaŸ¸ÑÖ”™é3±ŽÕõÉtºï¤TïÄq_Ÿ/Ûp´ª£[ÿ%G[êÙ7ÓÖNŠÊøéì?ÀOo#±žÀðleeeMŸ>Á``]„O8œÀ—ʧüpºž/9÷VÚW}»Z«}ï`Þ¦‹%Ž!¡ÜÑ£kÜp¶uu­½|iÄúÃÛ—$Íá§kGðÏé1¶òû‡ò„½ŠMó¬à|ÕÔ¬d¥ CÀ3U__ýúõ#GŽ`]„[x;vˆe“6Ë•¹ïg:÷¿¶u÷ÎþíÂízžOrŠC` †b‹bo0}FSnîÜßο=1êß³âô—J¾“åÅa,þã²T¡þuQ¢á5ÐÓ³’5ƒ ÏÔ¾}ûØlö”)S°.Â-\…€‘tÂw'µ(šýÎ oŽ­¾½¬U˜ºù´HfÌ ;8bX¡9@ˆDïÄDº“Ó—®—·Š¼2QϤù±þ òÜßÎËTêíK“ሟ!8 AVVÖÌ™3mll°.Â-ü|ÊwJd¿?I""Wß™n˜N—6üêH/Ý.hÖ,˜ôCB‚33³±_iöèÛÓ£¼O¾>õhQý²íWµð£üÙéîK ÏNyyùÝ»wáuQá$tˆeã6'+k§»Ù÷-õän}ÆÏç>>Ü)SzÛ_KDspàNOoVh¿9QÇ“èÛLJ¸Ÿ{sÚáÂúeÛ¯ÂógE,3™L¬«0ž•½{÷zxx¤¤¤`]„gx½JõÌŸÏÉÕêÓoLu´í»ÜW^õœ_/8„‡û$GˆÄ~žÁjQ˜vÓ3…DêèÇ*ÛEúö—Ý/ß}«úÓc·1,O$ Ðà¡(ºk×®9sæà¨dLÿç¥Ñ¢ ¶^ªé_|;Ý‹Ý7 °5§rñ¶ËÎÑÃ.Iþòtá¯Ù–‡0@O¤   ¦¦Ž@Æfñ!à•×.V¶œysª¿“¾ñë÷Vì¼æã>2ÃÚ,‘LæNªe±S¾?QÞ&Ô·/ˆ Ø8;~ÕîœC…uýì  ÐÉÊÊ 5jÖ…@8gÙ!à‡‹¥Ûrïm[’4Ü«oÆß/Ùå/ï¸êã6b†µY‰ä7yŠÖž3vãñÒÖ¾þ€µ“¢–$½¸í \Wøi (ÚÓÓC4HfÏž=óæÍúÿ,8\­j{çÀÍeÄÎÁÕ7ž,i|-ëºsD$LOŠ@$ùNJÕЙ“7ŸiëîÕ·ÿ²0q„·ã¬ŸÏ ¤ ˳hR©T«Õ ҵk×Z[[.\ˆu!þYj¨ý?öî;®©«ÿøÉÞ„=d#( ¨,EÜ"p¯V«­­V[kkûë´u<ÕízWµu]œ8‚¢à`ïM˜I$¿?bEdrn’ó~õæpsï'!r¿9çÜskÃöÆÌeÿùôªÆ´bÁüý×xŽNÖ~£!fÓ^$*Õ>hz½œ8ý÷«¢–6e#…DŒx/0l›\Þí®555ô§€Aëa6lذ!C†À‚è>­,ÚäòeÆ›qû—S5–Õ‹ƒ~¿B12¶7Íì72ƒn4ýYUã¢?¯«Ö à³h'VOº•S¹ýÒC¸ñ´”^Ôð:¤RééÓ§Ñ”@D3´²ØzñAZ±àô;S9tвEÚ&Ÿ³7F¨ Û¢«_ÝÀÀ~jà匢o/ܳp´›eû"¬+Üx\VoDF+©ÛÂbиñ[/¦žNÍS5®Ÿè:ÂnÁþ849 ¯š›› vM ‰2™ v -†a˜ŸŸŸ ì ˆ^в"@,m{ûhât÷Aom-ûëv–œm=n{b0m¤,ètz[ê‰„Š€~‰D‘‘‘h,Ñ-+¾‰N©µ|cœjîQnuãZì–©Ç0ž½=Ôh:ÈzìXÀä,þ3^5Ð”ÃØ»4àÐíçñ™ep³i‰DP€ôÂ… ZZZ-Z;¢/´©¸“Wùslúž…£Í¹/î m“‡í‹£òxV¾>p³é$"‰d;eê£ÒÚo¢RU!žv F9®ü;AuùÒ#T ½„aØÄ‰MLL`Aô…Ör…b}ø­qÎË}«w^M{Z^o=n< 5/D»Ð ¸fÞ>;¯>º_P­jüyþèz±ôû+iƒi‰DB¥RIú1eýV[[{ùòe4€h’Öœ;ÝÊL/­Ý»l¬j àiyÝÖKͽ½èúq›vXL‡ºq,ÍW¹Ñ*{1(`iÈÜ:ÇëÇØGï=ˆtC"‘èI7@EÀkˆˆˆ ‘HsçÎ…Ñ#ÚQD’OÏÝÛ8y˜‹™¡²E&W,;œÀ466s÷€›M÷À € ÙU X;ÞÍÅÌpã©;siT ½aXPP—ËíySQí(v^yD"> òTµHzö¨H`9Æ åÉ•Ã6ññŸ+iª+HDÂó|#ÜÈ*‡›M+477£"é^iii||< @4L Š€’:Ñoñß{2©Ê–z±ôÿΧ» ewÿ\D]̇ §°9›Î´_8uˆõL›OÏ¡Ë{¦o=mmhÒhŸ9s†ÍfÂè-(¶D§ÚðÙï´/ ðUTJ Zz{CL¥o$¢•ÿØÈ´ü«OJT߇ùÜ/¨ŽxX/—vhmm¥R©°Shê è ÃæÌ™£?Å"‚x/žWÔÿu'óóé#HÄÝþ¹Õ{o>59ŠD¡Àͦo8V–|;ÛÍɪ…áÝ-ùsGÚu_ŽÖŠï–L&Ó“K*ú%;;ûÞ½{h,Ñ<¼?Å>¶3â,ñqRµ|•Â4仺BL¥·,}ý2JkO¥æªZ¾œ1òiy]Ô£Bˆ©ðO¯Š2™ŒŠ€¾:uꔩ©éÔ©SaAô®‹€òñ‘»Y›§ §^ä|\R{ò~®ÉˆQh> 4#gÇÞvM IDAT§Ï#STk³æ³ÝqÝ]°;zU ž€~8~üxXX™L†Ñ;¸.~ÂgÒßݾ:Ю¦qŒø†v¶Sé93Ï5Mgä«Z>ž:ü~Aõ­Ü ˆ©pN.—‰¸þ·¦F¨è«ôôôgÏž¡± üþa’´Ê$=[=Ö•F~ñªP <’g<Üu@D30à;:l¿òHÕàl>ÊÖø×ëSáê @ºa˜­­m@@ì ˆ>ÂopöA~HºvÂPU˱é¶¡ƒÄTÀÔÓ3£¤¦ãe&¹G<,¨ll†˜ ÏP€¼ŠB¡8~üøüùó è» ~‹€ÿÝx:ÂÎÂàŽ‚š¥‡ngò† EÿT cðø––?Å¥«Zz90¨Þz1ž¡"y•»wœOÊênåV¼Ð~ Àñ{9R¹]€FnîqÏJT÷ ‘IK}&=G× v È«`æââ2räHØA=…Ó"àxr¶ Ÿ=ÙÕJÕòû§<'’Þ¬¸‚s¶6tó`RûWÿ£]òkšîäUBL…[r¹ÈËÚÚÚNž<‰ºˆðX(KÎ]êëDü§ç?¹ êYY­êÀ hèéÕrú¨è% ÃÆŽkii ;¢×pW\}RbÀ ú;™©ZÎ¥²líà%B^‰ÊfsŒ;žõ§ ô´¼®P „˜ ‡ÐpÒIccctt4ê@ Ã]û¬dÂ`Kò? ­?+¯/¯X‚› y¦õ ÈE€¿“‹FŽ{^ÒÍSô^ P(”ÖÖVØ)ð.**J.—/X°vDßá«P(ÀÍ슉.íýc1OKh4ÓÔb*¤\këAS^M£ò!Lí`Öñ’èÙp*zð)S¦ðù|ØA}‡¯" ³²^ ’Œql ¸žUÆ´° ð•Qa›š‘)ä„Ìö³¾¿£ù­tÀ¿èÕp*zTUUƒÆ<À×Éõvn%“Jöôââ@…$fW°,Ìá¦BºA Ù¦¦7sÚï#ìïd–WÓXÞ †˜ oP€ttîÜ9*•:gÎØAgE@rAÕHc éEªœê†z‘„mŠŠ\c˜š'd·>v¦¸_P 1ÞÐh4©T ;…† " G†Íš5‹ÃáÀ‚ 8+ÒŠ#mŒUïåW‘H$¦±ÄHHXf¦…5 µ¢åCÕÑ„›V,€› WX,–H$‚BCPн›7o¢±'pTÈŠŒ²Z«ö™2iÅ6ŸGЛ;¯h)¦±±B•´Ÿõ‡Y=.EE@;&“‰ŠDéôéÓÓ§O‡AÀU[Ý(jifÝ^<(Pø¨ï(L&ƒÉx\R«jñ°âw|ˆ°X,‰D¢' " {†………Ñh4ØA\™ €!æmßå —RÉÈÈ+(õõ@¨'àe±±±`Ñ¢Ejܧ–~<ÜÑdÅÑ’:!xg_RN¹ªÅûûóf¿ÝîøuÖéç(Õ™ÉñÇÝ~ȨËÝàr ±ã©Ë=2@³qî¸ç?bÚ7ˆÊ˜åCºk—‡=õt·O[€ÓîhÕN?GuÚI7ÿõ©÷/¼Û«þëÍ9ŸžÜz1Uõëû*ò¾Ç·§a|”pjâĉk×®íÓS\]]QQQª–ˆˆˆŽÿl}}}‰‰‰Ÿ•›› pvvV>|íUzóD•¼¼<Àýû÷ûôbuÛ²eË|}}Õ»O-ýxèmï ÀËÕ/z:|õ—¶É ÄuT°G¨þŸ3r<@ZšhÎId­™P(@¡tš7Ðq4 ;€LüâZö–²ü.Ñ£îöY^`{Žm߸Ãÿ÷¨ÇH½áýÛ¾OO$‰-­í+ÅRÉÄŽŸÏúvS¥üü|@@@û`üø}ÒÓÓÊåç øç¯3   àåöuûþ=õt"‹###·nݪÞÝjéÇÁ¼J¯yq²é åÇNÞÅ)GÑö¯¿DDj‡Ë Ôt¡Î@ì³·zýÂû¹ýë=‘Ð¥Píø|¾Úÿ *ÿÎvy_¢.ÏÁ}ݾODE@'.\‹Å .ÔðqñùñÐ=mmmd2¾Î¤}‚—942 ÐiP¹Ó=H„oªþ¿éÁ ÕÊ@wt¸Iî²S½·,í»<ÄëPv Ó’Ú_£[}xzO‘úúÂ{µ=PÈÚúúD…\F£´œZZågx FFF}í °··ܼÙþ¸qã_777@rrr—½|/ï°7Û+ç{·µµõõ‰*¨èð &˜››«w·ZúñÐ=--- vŠþÃËŸiå C9( D'“:}õ,úa}Óƒr±°)5¡øÇ†ÁÓyk¹gל?(-+·4+¤-’¢¬šˆÏßÓËÊ9}/âuÌÿ°Aøð¦¼Y$|x³ø‡ ½z‘úúÂ{³=™g¨‹;-—JúôD…L®¬ä”¤2YLJH?&Ξ=°~ýú7n…„„„>ø×`íÚµÊÍi¿DpêžK/œÚ1yû%‚) Ó…ë_õ»™ïÖ±±ß—v·Ï˜JŠÑ¿ÊÃñs¹7{©¯/¼Çí‚WtÙÞã_¾DÐ'ºD°ÝÁƒ9NŸžÒã5` …býúWþ^”ôuû+:zùDå“;NXÓg‡¢Ñhuuujß³–~JKëúÐãö{öìyï½÷lmm•_èûq åø(ê PÂ0,((Èpn‰®¥Ý£í=nÆlŒ>ú{{ˆ÷»ã†*¾Ý:‘Uë0+ü³’]ïøq«êÔïÅ»ÖsFM¼/vu’·¶><|øâú î6Ê–9ÿ½Ê¥S¾…î›þBRRR@@@YY™……EÏ[k92™|ôèQ´DnEE…µµõñãÇ5?+јeË–‰D"Õõ™Z/=#½Óº³²­_|>wSˆðáM™¨±µ¦¼&â@Ù_ 'Ï…KÍÚ$-€Ž·~¨J:.XYYJJJ`ÑÖÒ‚§OŸf0ÁÁÁ°ƒ HÛ{ptaC§ÕæÙtis3ÄÏ P(ááá , qô¨P'¸[ñÒKÛ‹w+ž¨®AÑÕÍ©ühàfÙ¾ âãRAÇŽDÉÊʪ¡¡A(Ôýi.z>œœœ——‡ÆôAEE@055…¤ÿpT<¬øJÚ¿úû;šËd2Qu5ÄHH„Žf†|Ö‹¥š¥‚¦Žˆ’¥¥%@Fô¼À0lðàÁ^^^°ƒ ®²²ÒÐÐFÓâ…ÑðUŒv0»_P­º¡°½1Ç„ËVVÂM…t¯¥ªb‚S{oØíÜJÀG-ž)3@”·{)..†dÀés “ÉNž<¹hÑ"ØAM())Q.ª½ðUø;š·´ÉÕ¨ZÆ8š6W¡"¿2ySuÍh‡öSþ­Ü gSc6Z.°3ƒììlØAœ> h,@O<{öÌÅÅvŠ×‚¯"ÀÉ”kÎe*¿J*Mt¶•—+rˆ©n«*ÛZÛ&¸´ßçVN¥¿£O“PŽŽŽ¹¹¹°S 8*•ª·1 1b„««+ì ˆ&dff¢"@ÍüL³ËUgzØ´HZD¨3§ŠŠÍ Œ_¬$i•Ý/¬òwBc]srrÒ‡"@o{ZZZΞ=‹ºô„L&ËÎÎFE€šÍp·¹ö¼TÒúbZ€“)×Ö„ÛP¢ûèZª¹¤8Ø}êaBV™XÚ¦º¡0Ò‰££cNNìNo‹€+W®466¢ z¢¨¨H"‘ "@ͦ»KÛndµwÌr$..‚ y©PØT[8ÔZÕr9£x˜•‘…ºmZהà …îÜ6¢Kz[`6f̘Aƒõ¼)¢ýž?@E€šYóXCÌyWŸ¶õ_èåØXSÛ\‡ÖÆÚœ‹1uhû䨫OJ:ÖH'NNNb±¸¢¢v¥ŸE€P(ŒŽŽFcú#33ÓÔÔÔÐÐvׂ»"0{¸mÄÃÕ—%'33CVŒ¤j¦¼Ü¹#ìÈÿ,‹ö¤¬.³²~öp[¸©ðÌÑÑ ó#ú91022²µµuÁ‚°ƒ ¢³>‹€EÞŽ‚¦{ùUʇDaáHû¦¼<¸©N$ 5‚£T-á÷smØèÒ€nXYY1 Ÿ¨Ÿ=†Mž<ÙØØvDCÒÓÓ‡ ;ÅëÂc0ÜÚÈÕÜðtjûY•¿«°¾¾©¼¼›g!Vóü™Ÿ=ÉÕRÕr*5wîb(¼#ööö¨Ð= &&è©Tšššêëë ;ÈëÂcawæAžüŸ!aÖ|O“ÚçÏá¦BTryCvöÛþ.ÄÎùiÅ‚¬Ê†°‘vPsi'''ÐÃ"àìÙ³d2944vDC?~,‘HP0PVu-®^JoŸø¶¿KCA¾Lÿñ©¡¨¨¥Yò†ß`U˾ÄgC-xh, G¨'@÷`6sæL‡;¢!ÉÉÉ\.WV…Âià`Ìèby 陪e©¯…H¨y†:pA‘>eˆµ½ñ‹?y¢–¶É9oùký pss{òä‰\®Ë‹`êÛÄÀ’’’ÄÄD4 W’““½¼¼tànÑø}oq½”^\Þ V>4`P׎R“þHŽî, ›°²²¾¬ü‹éžª–³óš[Û–ù:CL¥-<<<Äbq~~>ì ˆN§K$Ø)4çÔ©S\.wÆŒ°ƒ šsïÞ= x.掴籨ÿMxªjy‚{«¤¥.OÇ»Rñ¯&=}Ø ãñƒÛïðëõŒÐvf\ÄTÚÂÍÍ@ ¤§§Ã2€ †\.ןΠÃBBBèttÓ,}Q__Ÿ™™éãã;ˆà· SHë'ºÿ‘ðDØÒªl±5bÏ÷r¨IKÓù×𬹮®6?ÿó áª–Øg%©…5›=»y¢Âf³íìì222`@ÊÓass3ì š•••’’‚ÆôJjjªB¡ðöö†D ð[ÖMp“Êd‡ogªZ¶{576 ²2»y2 *îßw³â/å¨jù)öñ„Á–£lÑåѽåîî®ÛEƒÁzS„‡‡›™™Mž<vDsâã㬬¬zÞ÷p]ðY´ÅÞN{â2Ze/fQ9™r—x; ÒÒ:=¯ ·Ä‚šºÂ‚-3Gªx\Ró´äƒÉîPsi=)ôdZ†aóçÏ'‘H°ƒ šsåÊ•   Ø)Ô×Eà«™#KëEûo¶_&ðͬ‘‘°úÙÓnž… ò{÷<¬ÃFØ«Z¾Œ¼ïmkâi/”öqwwÏÊÊÒá!sýHKK{þü9 Ð+UUU> „D=ð^ØðÙo¸n¿ôP,mS¶8šp7MVy?¥µY 7›¾©ËÏo(-Ý»Ä_Õ p/¿*úqá·³GAÍ¥}ÜÝÝ[[[33uvTKz0 ³³³=z4ì ˆæÄÅÅ‘H¤I“&Á¢x/ŸNó¬·ìMlÿêÿY'‹B¬|øb*}£É«î'‡xÚv0S5n½øÀ×Þ4È Ý8µo\]])Š_  '=r¹ð… ÐZÙú$66ÖÏÏOg†Ò‚"ÀšÇZ?Ñ}Ûҵ¢k2©;B¼ªŸ> jàfÓIEÂæ¶_û¬äbzÑÎ0]¸RVèTª³³ó“'O`(z21ðöíÛÅÅÅh,@¯(Š˜˜ ZQ¾ž5’A%}y_Õ²&`è8g‹’„4CP$uu•R·Íör4á*[ZÚdkO$-òvì¸ZÒ{:ߠ󯹹¹ >¼çM]ñäÉ“²²2Th›Fù6Øë`ÒóçõÊü±xŒ¤¡¡Jw¿Nᅔ߹5Äœ÷ádUÛþ›ÏJêD;Bta­ (ÜÜÜt¾Ð힀ÖÖÖS§N-Z´vD£bbbx<Þ¨Qº3J;ŠÀ[þ.ìùkŽÝTÝZp¨ïë™#*SîKêêáfÓmÕOŸ4”U~s…ôâÓRR'úò|ÊÇS‡«î€ô•OAAAee%ì ‚D"Q©TÝî ¸víš@ @cú&<<<44T—®Õš"€H ~s¼Êß®·õÿ|ú?;Ó¢k±rYÄl:L,”Þ½»u¶——­‰²E¡oþoÍc}5s$ÜlZÍÛÛ›@ $''Ã2P †n÷`æíííèèØó¦ˆ®ÈÍͽÿþ‚ `Q'­)Vü&»u¿¨V¨l!‡ß' Ëï§Àͦ“ä2Yé„Q6ÆŸL¦jÄîçÄg–ý¾ØŸJÖ¦Þðù|GGÇû÷ï÷¼©vÒí{577GDD n}sæÌ[RËþŽìeÊa¼y8A5(àhÂýc±eúã:¾-%II QÓ‰UÉÿÜ.³¸Nø>vë­1®],áfÓ>>>¨'@K]¼xQ,/\¸vD£NŸ>B&“aQ'-+˜Tò©w¦ÜΫØv±}‘€c¯Ÿè^/®FW ªMezº ;ëÜš©ª+ÚäòÅ®›0~]4n6Ýàíí}ÿþ}]½N×á"ðqãÆYX KcôHNNNjjêüùóaQ3-+#mŒ·ÌòÚ~ùAjaû)ÿ‡¹~#ñ‹ã¯µµ´@̦3„åååÉ÷¾œ1bÊö;düpõñýª#+'2©:UÃâããS[[››«›·Æf0º:ÐÐÐpéÒ%4 oNŸ>mjjª3 ªh_ø4hx€“Å‚ýquâ§|*™xþÝ@.ÅÆ(d2¸ñ´¤¡¾ 6&x˜Í7³Ú/ƒ¹‘UþuTÊŽÕ Aä59’B¡èꈀÏ ˆˆˆP(óæÍƒѨ³gÏΞ=[—® PÒÊ"€H œzgŠ(æï‹“É_ô¦Z2¯~ÔV'(NLºÙê mÍ’Â+W<- O¬šDüg1ÔASØÞ˜Å>Ž›¦ëþéHïÑétwww]¨Ãs0 äñx°ƒ š“žžžššºdÉØAÔO+‹ŸE;úÖÄÄìò—Û'¸[ò#ß ¬ËÏ-¹{b6í%“Jó¯\6¦.¼?AyÑçß*“¿q8ÞˆEÿm‘?ÜxºÇÇÇÚ¥²²òÚµkh,@ßìÝ»wÈ!'N„Dý´µø;šÿ0×oKtê™yªÆ‰.–×Õ>}Zrç6ÄlÚHÖ"ͽpÁPÞ’ôñ,c6]Õþîñ›‹gÖL5`P!ÆÓIÞÞÞ©©©­­­°ƒ¨Ÿ®œ9s†Á`Ì™3vDsÄbññãÇW®\ ;È€Ðâ"ðÁd÷S<–þy=>³LÕ8ÔúЛãª2ž”§¦B̦]ä­mq±ÔQìÓ­ Yªöo¢SŽÝÚ‰[† IDATËŽ~Ú0k>ÄxºÊÇÇG"‘dddÀ¢~ºÚ€aXpp0“Ʉќ3gÎH$TàÔÎ0ßén6‹\Ë­nT5.óuÞ¿, üÁƒÒ{wÑü€ÉZ¤y—/’jã7Îlf j?‘œ³õâƒ_úOŒVC† a±X:9" “=·oßFcúæÀÁÁÁÆÆÆ°ƒ ­/HD‰ՓM¸“w_(®ªÚWu=ºrbuzFñ­›ºz)¶Z´67ç]ŒfH„·6{XµÝ~\¸â¯„ϧX3nÄxºL&3&!!võÓÉž€“'Oòùü   ØAÍyúôiRRÒêÕ«a(Z_˜TòÕf˜rcwE Ú뀥¾NgÖL©ËÊ*ˆ•·¡› tAÒPŸÉ­·?™íbf¨j¿˜^4woìÆ)ÛæxCŒ§Æ¯“E‹Å …=o§U0 £P(°ƒ šsèÐ![[Û©S§Â2Pt¡pè” ï1©ä™¿_.o«ÚC<í’> 5•Ù‘ç¥"]û“ôš‹‹³ÎExš2~Úñ~€ñ™e Ä-övúO(ºSð€?~|yyyNNì jÆb±ÄbqÏÛi'Ož>>L&311v5c±X"‘v u ·²²?~<ì ˆæ:tH,¯_¿v¤;EÀÊuãã`uÜQÙU ªv7K^Êÿ…Œ0geGF ²³!&Ä…LV|ófÑÍÄ'¹E¿È¢µ¯|2%7ô1«ÇºþµbYw+_\¡R©¾¾¾7nÜ€D͘L¦. …ð èð7B¤™LöÓO?½ñÆFFF°³ ]û@³é×>šioij3òVn…ªÝ€™ðѬõ†&Äݼ©·SZr¢£Dy¹§ß™úã<¿Žgúc/9xý³ Ïßù£>M?~<ê À¹”””ÜÜ\4 W"##‹ŠŠ>þøcØA–®.»qÆÜ‘ö~¼°/ñ™ªL$þ<ôÙ5­…ù9çôph@™™uîœ#<ø"tîH{U»´M¾â¯„¯¢îc«'7Û bBý4nܸ‚‚‚ÂÂBØAÔ‰Åbµ¶¶êÌ:H†9;;{{£y²zä§Ÿ~š3gŽƒƒì K7oG&ÿ·$€Ç¤½wâfYƒè›Y£T_mCGØùÚ›¾ùwBüùó¦ž#Ì==‰:wCˆ—IEÂÒ[·ë‹ ÿ/Èó›Y£(¤öâ¯F(YrðúÝüÊsïNw1¤Þòóó£Ñh‰‰‰Ë—/‡EmX,@$ö¸1ÎÉd²ðððU«VÁ‚hÎ;wnß¾­«÷÷ꈠÛ×Ðÿu;ë½7'ºX{kŸÕ>ýM¡ÿ»ñtó¹{&ÓrLÇJgÃQ(äUU)©¶|Öß+Æv0ëøÓ”Âê¹{cÉDbÄ{hM@ˆ\]]8;ˆÚܺukìØ±¥¥¥––Zÿ+>>~Ò¤IÏž=suu…ÑyóæUTT$%%Á2àtp8 £cßüdö“²:¯ç’ ªTíX;ahζ…“mùY/ä\º(©«ƒ˜s€Ôåå=?uº2ùþwÁ#žn™×±P–A?D¹YòR¾E\ãÇ×±¹ªžØAÔðáÇ£ @äääDFFnܸvMÐñ"àek’òy˜³©ÁØ]QÛ.=PÝz`ÎeF¼;õøªI,aCfDDyjª\W†0[ ccóââF™1“ÿ/äÓižçV7Iæü÷êúð[›§ ¿ð~PÇK(ÆŸ]VVÖó¦ZB¹º¾---gΜASõÊ—_~éáá;ˆ&èøp€ŠBv_{üyÄ}o;“ÃoNp2åvü©XÚöcÌãﯦ)HOOã¡Cµw¢€T$ªxð@™iÍcÿ<Ï·ã@¥ ‹Þ>šH%¾5qœ³”H'"‘ˆÇã9rdÑ¢E°³¨Gii©µµuRR’¿¿vß:::zΜ9666°³ š––6räȨ¨¨Y³fÁ΢ úR(=,®Yög|~MÓ·³GmœâÑéRøÊÆæï¯¤ýïÆ3Æ÷ð0vu%Q´éæ¹- Uéµ™ÏMØŒofŽX9Æ…Jþ× ¬jjþàäíðû¹ ¼ö. @¸2zôèaÆíÛ·võ¨¯¯çñx111Ú¾Þê’%KŠŠŠôalQ ©ªªº}[_nF¯_E@Ú&ÿþJÚŽËÝ,yû–xÙštÚ ¬^¼ójÚ¤ç2@乸˜¸¹Ñ¸Ü.w…Måe5éu……Ö<öæÀao¸ÒÈÿêÉ+ßÉúäÌ=&•üûbÿÙÃmaEE^å»ï¾;pà@QQA'ihmm¥R©!!!°³ôŸP(433Ûµk׺uë`gA4áîÝ»£GŽ2e ì,¢wE€ÒóŠú÷Ž'%f—¯3xGˆ—ÑiƒZQËÞħ»¯=› ­­øC‡ØØâí¯³L*dgÕ={*¬­ncüYàðy£ì_^éï^~Õ†ðÛŠjÖNºmŽ7‡Žn‚GÉÉɾ¾¾éééîîî°³¨•J=|øðÒ¥Kaé? ÃÞxã²²2“Îß4mÚ4©T;ˆæèi töAþæ³÷j„’Ï‚<×OrcÓ:Ÿ¥mòèÇ…oeÆ<-¦3,[;C{{Ž¥sB¥¬EZ_TØTßP\B'—ø8®òwñ±3}y˼šÆ-Ñ©ÇîeObýóüÑn–<ͧEzI.—[XX|òÉ':³BÇÛ¹sç;ï¼;HÿÍž=»¥¥åêÕ«°ƒ š0qâD˜ÈÒ'z]ZÚd¿\ËøþJ™Dø$pøÚñn×ÒW)­LÉ=‘’÷  ŠJ£±­qmm ¬‘hšVoihl(*l*.j*/'Aîƒ{9Îñ´ePºœ_Ó´ýÒÃ#w³\Ì ¿ó™éæ4ieË–UVVÆÆÆÂ¢ÖÖÖ›6mÒÞ묅…ÅþýûW¬X; ¢ &L “Éqqq°ƒh”¾JõbéîkwÇ¥Ó)¤uÜÖŽw3áлܲP ŒHË|\t+§B&W˜SLÍØæælS3 ‹©ÞT …¢¥¾AXY!ª¨h©ªhªo4`Ò§»[Ïf3ËÃöU½úJ?Å>¿ŸkgÄÙøàƒŠŠ .îg!¯/<<|ùòåiiinnn°³h*ÚÕ%{®¥ÿïÆÓf©l¹ŸóúInî–¯\BGØÒzíyibVEbneZqu[›œF§3ø< G70¤q8T.‡Æáɽ]˜¹M"iij”66µ45IêêÚêëDuõmmmmŒƒÙX'ÓÉ®V>v¦$b×gt¹BqåIñž¸ŒØg%C-x›§ _êë„î¨]ª««ÍÍÍ###uãÚ¤#FLŸ>}ÇŽ°ƒôÓ¤I“x<ÞÙ³gaAœH$ruu9sæÞ½{agÑ4Tt&li=póùžkéEµBGó5ã†Ìå@§t·l€¤U–V,xT"xX\“R,È©llK”?"“É4L£it@ Èþy³ @Èd²I«¤¥¥¹E®‚™ËÍÂp”Ñpk£ƒŒ]Í »ÿ&_V/>tûùÁ¤ç…áX'óÍÓ†Ïò°E_þµ”···ŸŸßo¿ý;ˆŒ;vÔ¨Q¿üò ì ýQZZjccsòäÉyóæÁ΂ ¸o¿ývÏž=YYYz8T7o ô:Ø4ÊÆ)&¹Ç>+ùûNÖ;Ç7œ¼5g¸Ý/‡)®Ö®¼W¢SH~¦~íSóš$­ù5M‚¦ZQK­X"¶ÔŠZä E¸E¹…DdÓ(42‰Ï¢±i|&Ý”K·3âØò9]âeµ¢–ˆ´üS)yן—³éËüœVŒvASÿ´]PPPxx8ìêÁb±Äb1ìýtúôi‡£]2H÷ wîܹuëV=¬ê èQ½Xz:5ïDrNbv¹!“:Ý}PàPëÀ¡Öæ\5Ïè¥ôÒÚ˜§%WŸ”$d•ÑȤ9ž¶‹½¦¹Y£žÝ ¼ïNvv¶““ì,¯+,,ŒN§Ÿ8qvþðõõuuuýûï¿aAÜÒ¥KSRRÒÓÓ©TmZN]PÐ[¥õ¢S)yÒ ofW´ÉåVüqÎþŽæcÌ­y¬;®\¡xRVw3»âv^Åõçeå b“8Ô:t„]ð0[&õåè™Lfjjúí·ß¾ÿþû°³¼®åË—766FFFÂÒgÙÙÙƒ¾|ùrPPì,ÈÀJJJ7n\dddpp0ì,p " Ïš$­±ÏJbž–$åT<+¯—+–”V7k“Q.vìù®æ†¶|NÇÛ÷‰\¡(oçU7=-¯{\*È(­{T"hh–Ò)$o;“qÎAnƒF;˜½jz ¢,XÐÜÜ ;ÈëZ³fMnn®6^pµmÛ¶ßÿ½¤¤„Ü뉽ˆ6’ËåcÆŒa2™×¯_‡ôï36Â>l„= ^,½WñþÒy¹fEâå?ÄŸÿ÷w $­²¼šÆB°¨VXT+,kÕ%ÙU •Í ÍR™\Ñ(‘*ŸH$ T"`¡³é&úsÞdW+[#¶dž϶á³Ñõýú)00P,'&&jû­w´tbà£Gž?~àÀØA•——÷õ×_ñÅÎÎΰ³À„Š5`2™Ê?vt i¨o¨š¢ôŸµµµÏÙ³gu ÐÆž ÃìììôjáXý´nÝ:ggçÏ>û vÈP³¨ŠQ‹ÐÐÐóçÏËd2ØA^‹6 …ð àínaˆza³oß>4胊5`0ÍÍͰS º#,,¬²²òîÝ»°ƒ¼&“©uEÀ;wŠŠŠ/^ ;2€jjj6lذfÍ___ØYàCE€ žD½œ‡;ÈkÑÆ9† :ÔÓÓvd}õÕW$iÛ¶m°ƒà*Ô€Åb …BØ)ªí«Ö³X,™L&‘H`é­¶¶¶“'O.\¸vd]»vmß¾}{öìáó_yk½‚Š5055­¬¬„Ñ)!!!=‚¤ÿX,@‹:®_¿^SS³téRØA"–/_¾dÉ’E‹Á΂¨Psss@ÐÚÚ ;¢;Fecc£Õ#Ê"@‹¦`6jÔ(GGGØAòöÛoS(”?þøvAE€˜™™)ŠêêjØAÝA æÌ™£ÕE“ÉÚS477Ÿ;wM Ôa'Nœ8þüŸþi``; Ž "@ ÌÍÍhDQ¯9sæ<~ü8''v~Ò®ž€Ë—/‹D"ÔK¬«ŠŠŠÖ­[·víÚ)S¦À΂/¨P333€ŠDÝ&NœheeuìØ1ØAúI»æ``ii ;¢~ …bÕªU¦¦¦»ví‚wP ‡Éd¢"Q/"‘¸páÂcÇŽié]¾´¨' ¡¡áÂ… h,@Wíß¿ÿúõëTQ!¡"@=lmm `§@tÍâÅ‹sssSRR`é&“I ´¢ˆŒŒ”ËåóçχQ¿ÇoܸqóæÍ°³à*ÔÃÅÅåÙ³g°S ºÆËËËÅÅÃ0ØAúƒH$Òét­(0 ›:u*‡îú¡kÂÂÂÆŽ»}ûvØYp êáââ’••;¢ƒ-Z®¥÷ЊÛTUUÅÅÅ¡±´zõj±X|ôèQ"캆ÞõPZ:v‹àÙ²eËÊËË`é­XQûÌ™34-$$vDÍþøãˆˆˆ'N(çn#]BE€z¸¸¸ˆD¢ÒÒRØA]ãäääå奥#ZÑ€aجY³”Ó‘ššºiÓ¦¯¿þz„ °³à*ÔcðàÁ€ÌÌLØA´xñâ³g϶´´ÀÒgø/ nݺ…ÆtŒP(\¶l™ŸŸßçŸ; Þ¡"@=ŒŸ>} ;¢ƒæÏŸßØØxéÒ%ØAú ÿEÀéÓ§y<ÞôéÓaAÔF¡P¬\¹²¶¶öĉd2v¼CE€Úøùùݹsv D 4(00ðàÁƒ°ƒô›ÍÆy€aXhh(•J…Q›o¾ù&:::22-ýÔ¨P___T dåÊ•W¯^-++ƒ¤o¸\ncc#ì¯ôôéÓ‡¢±]ròäÉmÛ¶íß¿ßÏÏv퀊µñóó+((¨¨¨€ÑA!!!<ïÈ‘#°ƒô ‡ÃÁspòäIKKˉ'‚¨GjjêÊ•+×­[÷ÆoÀ΢5P 6¾¾¾$éîÝ»°ƒ :ˆJ¥.^¼øðáÃÚu*—Ëmjj‚╎?>þ|t¹n¨®®ž;w®ŸŸßîÝ»agÑ&èÓ¯6gèС¨@ÈÊ•+³²²´kÈ Ï=)))¹¹¹h,@7H¥Ò°°0‰túôi4°OP N>>>Úõ7Ñ"#FŒðôô<|ø0ì }ÀáppÛ€a˜“““¯¯/ì ˆlÞ¼9%%Ã0###ØY´ *Ô)00ðöíÛuuu°ƒ ºiåÊ•áááB¡vÞÂíÄ@™L¾páBØA5øõ×_ýõ×C‡ùøøÀ΢}P NÓ¦M#111°ƒ ºiéÒ¥­­­ç΃¤·¸\®P(Äá<†¤¤¤²²²¥K—‚¼®ãÇøá‡»víB#;ýƒŠu200ð÷÷¿xñâë瘟¥åÓO?µ··§P(áõwˆOA]¯N»Â-##£3füõ×_°ƒô‡Ã‘Ëå8ìºÀ0ÌÃÃcÈ!°ƒ ¯%))iõêÕëÖ­ûøãagÑV¨P³™3g^¾|ùõïù¶uëÖ]»v´µµ)[ôá$×zþ>¬[·.>>>##v^ár¹¼M J¥§NB_µ]fffHHÈ´iÓöìÙ;‹CE€šÍœ9³¦¦&99ù5÷£¼aŒrÅxö¦âB¡Ð‡7jÒ¤I...ûö탤W8oÓbccëëë—,Y;ÒUUUÓ§O·±±9vì‰D‚G‹¡"@͆ bggwùòå×ÜOaa!-hŠtB Ö¬YsôèQœ/Ç«„Ïž ÃüüülmmaAúI"‘ÌŸ?_"‘œ?žÍfÃŽ£ÝP ~sçÎ=~üx÷ßJ“’’–/_nmmM¡PŒŒŒUÓ •ÝÝÊ"‘HøGÇŸvê?vìØ„  i4š““ÓæÍ›T?UnÜÜܼ~ýz33³W]DÛÖÖößÿþwôèѦ¦¦T*ÕÒÒrÞ¼yqqqªŸþòË/^^^l6›ÉdN˜0!::ºûýwÙoße£X,^³f±±1‡Ã -((xÕûÖÍûÐiÏʇB¡påÊ•¿üò  ¶¶vÙ²e<ÏØØø‹/¾èôkêþĉ•+W¶¶¶ž8qvžá°'@$?h¯¶¶¶E‹¥¥¥]¸pÁÆÆví§@Ô-33“@ \½zµ›m^þE„óçÏwù£n~wr¹¼Ë^M77·†††ŽÇš;wn÷¿ô·ÞzëUG‘J¥¯úð¼jÿ]«S£òaXXXÇÝZ[[ ‚^¾o¯:œòahhhÇ-###;]DtäÈåö½y'ñcåÊ•žžž°Sô¬µµpîÜ9ØAÚ…‡‡“ÉäÊÊJØAþÉd‹/f³ÙwïÞ…EG "`@,X° › ¦OŸ~ùòåúúz©TZRR¢\çÒÛÛ[µÁËgÐ.Ï©XYY:uªººZ,ß¾}ÛÛÛðé§Ÿv|¢••ÕÅ‹›šš^‰Éd¶lÙRRR"•JAttt`` B¡øñÇl6û—_~)..–H$·oß é~ÿ½/lmmšššâãã•¥ýæÍ›_•³ËݾjÏžžž=jhhX»v-ÀÀÀ S‹¿¿ïßIüPN:¹wïì =c0ÿý7ìíæÌ™3uêTØ)~Z»v-F‹‹‹ƒDw "`@üõ×_T*µªªêUÄÅÅ›››w윧Óéª zY(×;KLLìØ˜›› pvvîøÄ¿¹ºº?üðÃfgg«~4|øpÀþýû»|â«ößû" **JÕ2dÈ«rö©¸sçŽò¡êþ{ZLMM•{óN⊗—׊+`§è™™™Ùo¿ý;Å €J¥:tv¤?¶oßN&“#""`Ñ)¨b±ØÐÐp÷îÝ]þ4<<üU¹©¶ée üúN"‘H$‘HTÎ!PnI¡P:>±¶¶¶ûÌ·nݲ³³ë&((HÙkÊ`0¯ªi^µÿÞuuuª–ÚÚÚNõPovûª=K$åC¹\Þe @P>ìÍ;‰+d0¯7Á''§;vÀNñÂÁƒét:Çwíß¿ŸH$âªWI7 ‰‚Á`Ì;÷U˼÷Ýw …âÝwßÍÌÌlnnV(ý^ME¡Pd2™L&“Ëår¹\ñÏùO9«ÂãñºßÕ˜1c²³³oݺµk×®yóæ±Ùì+W®|ðÁ½Lòòþ•'QU@sss/÷¦.4­c˜—[ªлw'.\H¥R= ;Hpu#A ‚‚”×, Z$**jݺu[¶lA÷V?xõ‡ŽKMM%—/_~ùGÊóP}}½ª%22²Ó¯ãåߎò¤ÕÚÚÚ±ÑËË œœÜM’þý¢•=á|>_¡Pxzz8Чý›››òòòT-W¯^íòeöi8 Ë÷áå/§ê¾¥7ï$Þ|üñǶ¶¶/¿¸2~üøuëÖÁN¡P(¥¥¥D"ñäÉ“°ƒ }E¥R?þøcØAt*ÐìÙ³}}}_nwrr|þùç ®®îÔ©Sfff=žÃLMM'NœPv(:t`nn~àÀüü|±X,‘H233÷ïß?zôèWíªKG-..nmm­ªªÚ¹s'€Éd*ŠŸ~ú Àáp~ÿý÷’’‰DrçÎN_Þá¤I“³gÏ.**jll¼pá Aƒº|™}šØåûðrŒ¾½y'ñ¦  €L&Ÿ9svî¿ñưS( Åž={¸\n§ ‚s†‘H$åÕ¼È@@EÀRvÄÄÄtjßµkW§þU—j›—ÏX+V¬èô,eûúõëÁ+¼jW]êrï¼óŽB¡J¥“'Oîëþ/]ºÔi{ÕUˆÚéB¾n.ìæ}èrÏ/¿ÀnZz|'q(,,, vŠî,]ºTU/Âåëë»lÙ2Ø)>8wî…BùüóÏaÑeøý릂‚‚Æß©±­­í‡~pvv¦Ñhß~û­jÔYµÍËçžúúú÷Þ{ÏÖÖ–B¡túi\\ܼy󬬬( ƒÁpssûè£ÒÒÒ^µ«.ݹsgÕªUÊ[3fß¾}mmmÊŸJ¥Ò~øaذat:ÅbM˜0AÕ‡ßÍþ:äêêJ¡P ôí·ßªîƒÐée …ÂU«Vñx<‹5gΜŽ#/{ÕûðúE€¢§w‡nܸð=Šñî»ïNš4 v Evv6àâÅ‹°ƒ ½A¡P>ûì3ØAtA¡Ë­Ct÷îÝÑ£G'&&À΂è&ooï!C†9rv®}úé§ñññ¯7×´cÇŽÝ»w—••©jGÏΟ?¿`Á‚7*Ç%‘ƒ®X~~~ãÆÛ¾};ì ˆÎzÿý÷OžvìØ¼yóP .]º´xñâ7ß|óûᅦE÷¡"`Àmß¾=&&æÂ… °ƒ ºiÑ¢E|>ïÞ½°ƒtÃá@¿D0==ýÙ³gè~Záܹs¡¡¡Ë—/ß·oŸ>ß4\cP0àÆŽ»téÒuëÖ‰ÅbØYD£ÑÖ¬Yó¿ÿýO"‘ÀÎÒ.— ½'Ã0kkë±cÇÂôèСC ,øä“O”KÁŽ£л¬ Û¶m«®®V®À j÷Î;ï444„‡‡ÃÒ‡#‰T+6jžB¡8qâÄ¢E‹ÐIç~ýõ×Õ«Wùå—Û¶mƒE š`kk»mÛ¶­[·>|øvDYZZ.[¶ìûᅦx®}.—«P( Žܽ{·°°àÜÏ?ÿüá‡þç?ÿÙ×&t IDAT²e ì,ú²aÃOOÏõë×ãðÏ4¢6oÞœ ;HgÊ5z!†¹¸¸Œ9V¤G?ÿüóǼeË–O?ýv½ƒŠ !“ÉþùgJJ šïŠ —3füððƒtÆáp°¦´µµ>>áááÇŽ{ûí·Q€¨ÑªU«ètú/¿ü;H;(+755]¸pàÊ7üýý­­­“’’lll`ÇA@EDÁÁÁÑÑц-Z´Hu]yMl6û£>úõ×_ëêê`gyËåj¾ˆŒŒlmm7ož†‹¼Ê¾}û¦L™2kÖ¬ëׯóù|ØqPS``àÉ“'£¢¢–.]Šæ ê²~ýz"‘øÇÀò” b6uêTccc y™B¡øì³ÏÞ}÷Ý/¾øâï¿ÿ¦R©°!íPYpppTTÔåË—ñóÕ Ñj\.wíÚµ{öì …°³ðïž‘HTVV6ÐSjjjbccÑX´¶¶®X±âçŸ>|øð–-[Ðñ­€ <˜9s&ŸÏ¿té’­­-ì8ˆÖvvvß}÷ÝÆ5ôk×®EGG744ÔÕÕÕÖÖ–——766J$‘H$“ÉüñÇÚµk.ÀÞ½{7mÚTQQ¡\¯E$-\¸0!!ðàà`Øq. "/òóó§OŸ^WWwêÔ©ñãÇÃŽƒh½7†‡‡çççÓét :##ÃÃÃH$¾jÒk^^ž½½ýÀ?~¼™™Ù©S§îH BCC+**¢££½¼¼`ÇAº††ðÂÞÞ>%%eܸq“'OÞ¹s'*Î×´iÓ¦ººº¿ÿþ[ó‡vwwŸ0a«nÝëèè8 @IIIRR €+::zøðá4íÁƒ¨À3Tà›Í>yòä_|ñÿ÷+W®lnn†ÑbÖÖÖo¼ñÆ®]» \{²aÆ.K¥RçÌ™£Þc]¾|9##Cõ0<<œËåΘ1C½GAzoçΡ¡¡aaa7nܰ°°€é–ÁŸ¨¨(CCÃaÆ=þvD‹eff’H¤'NhþÐmmm–––]þ͉‰‰Qï±Þxã ÀàÁƒ·mÛ–““3räÈ•+Wª÷H/‰ÅâÅ‹“H¤={öÀ΂ô ê À£àààôôtCCCOOO\­ú‚h—Áƒ/X°`Û¶mš_ŠD"­]»–L&wj§ÓéãÆSûáˆDbVVÖ–-[œœœòòòètzii©Ú‚t¯¨¨ÈßßÿòåË.\øàƒ`ÇAz8emm·víÚ7¾ýöÛ°îÄŠh»ï¾û.++ëĉš?ô;ï¼Óéz0‰4qâD¦öc)¤€¨¯¯?xð µµµ‹‹ËÎ;ËÊÊÔ~8äe)))µµµ AAA°ã ½…Šü¢P(?ýôSTTTtt´‡‡G\\ìDˆöqrrZ²dÉwß}§ù™&&&sçÎ¥P(ª0sæLµèåKÏ[[[999Ÿ}öÙW_}¥ö#">|8 ÀÁÁáþýûLJéTàݬY³233§M›6uêÔ ؉-óÕW_åç燇‡kþÐëׯWž•ÚÚÚ49_D"ùùùíÝ»WcGÔCb±xÙ²e«W¯Þ²eËõë×MLL`'BúZÀÀÀ`ß¾}áááñññ#G޼xñ"ìDˆ6Ø0f̘aÆ©®´³³Ћ;"‘H†††»"õÊÏÏ÷÷÷¿xñbTTÔ§Ÿ~ŠVÔF¨Ð .ÌÈÈðóó›5kÖâÅ‹+++a'B´Æ×_Ý©3 ­­íüùó8ô† ”ÿ3vƒ@ DFFš››kìˆú&66ÖÛÛ»­­-99y FyÍ@E€6133;yòä… nß¾=tèÐÇ+КBH/8::.]ºTÙ —Ë1 srrZ¸p¡rßµdÉ‹J¥4_ìå/ a÷îÝ£GˆÃ! …bÏž=3gÎ3fÌÍ›7a'B^äK‘~ijjúðÕCžÉÉɰã Z ''‡L&ôÑG...ª³f^^ž­ì  R©"‘h ö¿bÅ ‰¤ú›F&“Ñ:§®®.$$„D"mݺU.—ÃŽƒ¼®ÎWñ"ZÍfïÞ½û½÷ÞÛ´i“ϬY³~ûí7;;;عüzðà±±ñîÝ»Š:23350H¿ê5¿ýöÛHŸÑË›¥u’VYsë‹Ù t ‰A!Ó)$“ÆcÒx,*ƒòZ”Èd²»»ûÿû_uG:S®ÇL¥RïÞ½‹Ö ¨ÐbƒŽŽŽŽ‹‹ûðǺaÆ/¿ü’ÍfÃÎ…àËõë×7oÞœššJ$Æ(Jvv¶z»èëÅÒŒ²ÚŒ²ÚœªÆÜêÿ‰¥mÀÒõ®Ìl쮨÷À M¸Ž&\޳©›%ÏÊÏcv·´€ªcƒH$r8œ¨¨(Íß3IçÉåòï¾ûnûöí!!!400€QTh½)S¦<|øððáÃ_|ñűcÇvìØ±|ùr4MÈd²åË—‡‡‡+{Ë;­H rrr^ó’VÙý‚êÛy·r*ÓŠÅuB›Fq65p4áÎô°q4ášpèÏFÑ=܆zº aR»ø›Ó,•ÕŠ%u"i¸¥Zج,nd•LzÞ$iX²<q4ów4÷¶3ér'"ñÿÛ»ï¸&î7à—V€öÞ[Pœ€X޶N*Z÷ÏÙV[ÛÚÖÑ娳Vź÷¬·(*CD@DDVØ„°dϻ߱`U.Àó~õŸ{¸ E½ÏÝ}ïû%ÆÆÆÚÚÚ¾ã^R]]•ðÇ,^¼þyéJ`)ᮃÇã­^½ú¯¿þ ضm[ß¾}ñîàïÞ½{#GŽ”Éd-ß×׿yóæøØlïjvù•'åÉE\¹eêÑÔ§g_k¦¯5Ó‰Åxé4¢è›l†!%õ‚'•¼'•¼‡%µIlnPJ!ƒœÌFøØ ÷±íic‚ ÈŒ38@ ~ÿý÷o¾ùæ?ü8 )))S¦L‘ËåÇŽûS>|AèjRSS¿øâ‹‡Κ5kÅŠ666xwp–““Êãñ^ÍÖÖÖíüÃîUŸI/>—Y\Z/dêÑÂ<¬Ã<¬¸ZxZwÀÅ!†!¹ÜÆ$67îYeܳÊz‘ÔÆXoœŸ#ûìŸWΜˆŽŽÆeÝä. Eѵk×®\¹2""âÀ0P—!  Â0ìĉ?ýôSEEżyó¾ýö[sss¼›x*..2d‡Ãy)±XÜæôgU{sO¦±+EFãœFøØõv0%q»-ŒbXziÝ•ì²ÓéEOo%×ÍÞtxþÐ^>VL¼ZêbØlö”)S²³³wîÜ©^§tIº,EÏž=»bÅŠÒÒÒéÓ§¯\¹òMK»‚î€Ë円†¾”rrr<==_{ˆL©:™Æþ;!7±kk¬ÝÏuB€s›¶Ï²Jͯnb×ò‹ë%õN£¸Z ­Éx"©Púš§út Sf¢G3×§[é:š0YN¦îæFRÛf-üBß?üB¡ ¤^äd6»¿çä>Îïø–A7wôèÑùóçÛÛÛŸ8qÂËË ïvÀ! ‹S(Ç_½z5—Ë5kÖ÷ßwº­†††ˆˆˆÇ·ÌçÏŸu"¿ª&ñÖ[Ù{“r›$ò±~‹C}ú»´6õž Ų9¼¤Âê´²Ú‡¥õyÜ…R… N§1 ˆzz$L£“étõ5“øªä ¥\ª”JUR&I|©DŠ ™Lt7gÚ3ìX!Î=l˜ä× ,àóù AôÒºÝ Ï§PHÄéÁnˇùYé¾ýÿ§nM(Ο?ÿðáË/^·n¼gÑåAèärùV­Z%,X°|ùrccc¼›8‰D‘‘‘‰‰‰ê@¥Rýõ×eË–iv¨Iÿ¸‘µãNŠa3û»/ õud¼ö£P Ë,¯¿ù¬âZ'µ¸Z,SÐuutX¦4c&i¬clL3d(ÔÿÖ§J¡ñùR^ƒ¤'khÖÖJÄb*%ÐÑô#O롞6ö,â†!”7·ÝÎÞ}/Űyƒ<¿‰ð35€3Y»¤¥¥EGG———oß¾}Ú´ix·:„€n¤©©iÓ¦M›7oÖÑÑùúë¯çÍ›“ tC2™lÒ¤I±±±*•ŠL&Ϙ1#&&A¾T¾éæ“ÍqOèÒWC}çð2Ò}Í)\…bñyœ#©³Ê„RºŽŽ¾­¾…•ž…9ýC¾;.ãó…Õ\!§JTQ.‰té£zØFõqêióÚ¡ |©üï„Ü?nd‰äŠ%¡¾K‡öxíÔ ÅÏ?ÿüûï¿÷îÝûàÁƒ0p÷! Û©««[¿~ýÎ;©TêÂ… -ZÄb±ðn t(™L6eÊ”‹/*•ÊþýûÇß½»ëî³U±éòuDσ½õh¯y þ”Ó°7)ïpja_¬Çd2ì ìôX¦H¿5Ž!âºÚ¦²2~I‰°¾ÞØ@ç³>Î3ƒÝÕ¯ ¾D,W³þúc¹ýi”ÿ‚ÁÞídÐݤ¥¥M›6­´´tÓ¦M³gφiºÝ”P(Ü»wï† jkk'Nœ¸bÅ www¼›G¥RÍž={ÿþýFL«E;‹ëË"z|3¬§>íågöb¹òȃ‚˜Ä¼Œ’¦1ÃÅÕÈÑñƒ^ô·ŸŒÏo,.æ³ øu¼v¬¹!Ñý\_û#l¼™µöZ¦­±þÆñA#}ípéV ÉåòŸ~úiãÆÁÁÁû÷ïwrr»#ÐÑ tkr¹üĉ¿ýö[AAÁˆ#~úé§Þ½{ãÝè Åuü°ñӋ±÷ú/Ÿ„X¾<†®F Ùÿt[|Ž@*7rt`yyXjé &Âjn]NNcQ±.•¼`çâPŸWœz‘tÍ¥Œ¿î<íïbóÙws#\ZÕ™™™Ó¦MËËË[·nÝ¢E‹þÃlN  €E/_¾üóÏ??|ø0$$dùòå‘‘‘x7> Ãbî=ûî\*S6)˜;ql=ZîPÕ$þýjfLÂ3™bìéaæåCÑëÃìImNNCNŽJ!Ÿâ¾bx/c½—ö‰ÏãÌ9r¯š/ùeLqœêG*•ê?þXµj•··÷Áƒ½½½ñîàBxEÑ .¬]»6555<<|ùòåáááx7Þ?v-?jïíGåuß}ÔëÛüè’\.§RŸš«J»šù×"jÖ³—‰»;‘ÜÉ^¸GUªúüüÚG”Rɼž+†÷2gè´ÜA¡B7Åe­¼˜ÞÆylf˜‹¯Vq‘ŸŸ?}úôôôô5kÖ,]º”ÜÙ~¿àý‚^¿víÚ7nøúú.Y²$** Þî2.>.yè.ƒN=2sH?§fŒ+Ñ?ã³W_Î#DÓ~¦>^DR'>= *U]γÚÌG$TõãH¿/Â|idRËÒJk£öÞ®HwOð©·xŽ¢è† V¯^íæævèС—nÿ€î Bx=6›ý÷ßÇÄÄ (:}úô¯¾úÊÞÞï¦À§DѯÏ<ØrëÉô`·mC è/Œž»ö´üǓ˄¦Þ¾½üHÔ.ò6ªPp3×fgY2twL Õã…!"™òËÓÉ'äÎìµy|0•ܕЗ——Ϙ1#>>~Ù²e«V­‚dÔ €Öðùüýû÷oÙ²¥¬¬lĈK–,gQ@2aw\ZiíßSNîíÒòK bÙ—§ïLÎg9;Yö ¢tÁ©#ä"75µ¶ `J_—­‚Yú/œÿÎf~ðޝ5óôœ¡]u†ÁC‡-]ºTWWwß¾}aaax·´„Ð6õÈÁmÛ¶ÅÅÅùûû/Y²dòäÉÊkæZ(­´vÜκTòÙyC_Z_çò“²ÏÝ¡«†ö]üÅ9~E'1†*÷|6`\/‡–_Êå6~¼ëF£X~vÞЗž’tvl6{Þ¼y·nÝš3gÎúõëÕó+ !¼…„„„­[·ž?ÞÞÞ~Ñ¢E3fÌ€S´Ü?Чî‹ânutf¨¡NóM~±\ùå锿rXÖAAÿy~ßÎU(+SSks²§»o›Üò™ˆ@ª˜v þjvùþiƒ'õvƱÉ÷E&“­\¹rÓ¦M~~~»wïöóóû#  €·V]]½sçÎ;vðùüÑ£GÏ™3žh§u×3¿?÷pþ`¯-‚[¾ ÷¸¢þ“˜[|©ÍÀFø5ˆ¦òòŠ»wÌu)gæ„Ú›jê(†}söÁ¦¸¬U£éß©çÍ»}ûöܹs¹\î/¿ü²`Áx¼ „ð …ÂcÇŽíÚµëÑ£G}úô™7oÞ¤I“tttÚ>|x†,;“²å֓ヾómù¥C)ùsŽ$ÒMM퇄uŠ·ÿ?…DR/®ªÚ>9x΀VRÞy7gщ¤¹=·Oêßs@}}ý—_~yäÈ‘ˆˆˆ;w:::âÝÐjÀ»ÊÍÍ=pàÀîÝ»•JåäÉ“ç͛׫W/¼›êÖ”(:ýÀ³ŧæ„Gö°oY_x"9ænŽ™¯¯MP_¡+†o†aœ‡«gF÷sß5 å«—Ÿ”‰ÝÓþðŒ!k­C‡-_¾EÑíÛ·?ïv@'!¼R©ôÔ©S[¶lyôèQ@@Àœ9s>ûì3]Ýnz¡‰#Ãf¾wôAá‰Ùacý4u¡LñILÜí¼*Û™..oþ€î¥¡¸¸üN|°“Ù…ÿE´3q5»ü“]7ÇøÙ™Ú)f,++›?þ•+WfÏž½nÝ:#£î>)2h'à}Â0ìîÝ»»ví:wî“Éœ1cÆìÙ³ºßSg-<ž´'1÷üüˆ¼m5Åj¾$âÏ«ùu"‡ˆazff8¶§…ÄõuÅ×®;Òâ– ·6jžføN>gäŸ×&õvÞ3u6?PϼfÍ;;»˜˜˜âÝèL €¢©©éäɓ۷oòäI@@ÀÔ©S§NÊd2Û>¼ƒÅ'’w'<‹]8l¨§¦XÆÞt¹NEröQ—œàÝ)D¢’ëרìÎW#M›_xIbs‡m½äö×d-››;oÞ¼ÄÄÄÅ‹ÿüóÏzz/¯•@ë:Óã.ЉΙ3'33óúõë®®®ß~û­““Óܹsïß¿wk]ÖÆ›Y;î>Ý?}PËð¤’ðÛy‰î±½× …Ë—/ïÙ³§@ xðàÁ¦M› €ÿ ‘H.]º´{÷î[·nY[[GEEÍž=ÛÙ¹+¼­%N§MúûÖ¶IÁ 7¯WPÓ²!V®«ï8l‰Ö-fx¨BQ|ý:ÒÄKX6ªå¬J{“rg¾wpú©A®8¶§¢èŸþ¹fÍ …²~ýú©S§´ó6è €•——wüøñýû÷WTTôë×/::zÊ”)úúp…úNâžUŽøóêÒ¡=~×GS,­öÛpQDÕs1‚Ó;¶ªR]»F4ÞÿztËÕW_JÿùrÆ?ó"F÷Äy”””… >yòäË/¿üöÛoa xGd2Ù… öíÛwóæMcc㨨¨èè耀¼ûê”ÊxÂÀßþ v²øçC‰ÿ^rùâ¾ë/6 Tç£àÀ[A ö•+ú QÊ7£mŸÇS C&퉻™Sùðûq- t¤ÚÚÚ¥K—9rdèС۶mswwÇ¥ ÐÅ@x*//?xðàØl¶——×Ô©S£¢¢lmmÛ> ‚ "™2xýy ‰˜øõ:åùR¹©"dCl±Xå<*’ ‹Å½=•LξkIA|3ÆH÷y„’)U7Ä6Iä¾ÛòeÂŽèG¥Ú¾}ûêÕ« ÆŸþÙ‘ßtm00àÉÖÖö‡~(,,ÌÎÎŽŒŒÜºu«]``àÖ­[kkkñî®Xt"©Œ'<>+L“dJÕˆí× ¥N#FBøoH4ªÓˆ‘•UØ–+b¹R]¤‘I'ç„Õ ¥ÿ;šØ‘Í$%%._¾|ñâÅ999Àû!hooïµk×VTTܼyÓËËkÅŠ666‘‘‘‡‹Åxw§¥¥ä¸ŸwøóPW3CMqá‰ä”’Z‡¡C)0SÓ; ÓéöáOªçMÐL ŽÏ=™ÆÞð¬z¨®®ŽŽŽ0`€••UvvöªU«`ö-ðÞAZ„D"…‡‡:tˆÃáüý÷ß‚̘1ÃÚÚ::::..]µ”WÝ8ÿXâ7~£z4/¼;áÙÞÄgöƒ‡èšš¶r,h&Ó>,ìØƒÂ­·²5Å¡ž6?Žô_r29«‚÷á¾µJ¥Š‰‰ñöö¾}ûö±cÇ._¾ì“<‚Æ­VPPpäȑÇ{{{GEEMœ8ÑÉÉ ï¾p¦P¡ýÖ'ˆ‰ßŒÖLn7¿*lËes?Ë|ÛëJªgU¦>¸²è#Í ŒJôGl“DžöýÇš§0ïÑ•+W¾ùæ›ÂÂÂ/¾øâ‡~€wgÀw€Vsuu]½z5›ÍNHHèß¿ÿƃ‚‚6oÞ\YY‰ww¸ÙrëÉSNþiƒ4  A,›¼7žammé«7½Oæ=z;ØOÝ·V UWÈDâÁéCJë…ë¯?~¿ß+111((hôèÑ!!!EEEk×®…>4  ýû÷ßµkWMMMBBBß¾}×­[gccãíí½jÕª¢¢"¼ìP¹ÜÆ/¤­ème¬)N?p· E쇄!0oÌûE@ì‡JH”É{okn›º˜1Ö~ÜççË+ê[=¸™D"IOOÓWÙlö„ Èb±²²²bbb¬¬¬Þ½wÚ@§¤R©îß¿úôécÇŽñx¼~ýú?~âĉx·öaa2dS¬P¦Hùv,™ø<ÄïMÊs$Áud¤¾eÿññ"ª­-¸paó„ EC|ÔÃnˆU¢hòò1Ķ‚—B¡;v,›Í~úô)‰ô„ººº+Vìß¿ßËËë?þÿP?¯w@§D"‘ú÷ï¿uëÖ’’’#GްX¬åË—;88Œ3æøñãB¡ï?”“iìÄBîŽ)ý5 €Ó(þòtŠ©·$€GÏÔÔ¬gÏåÿ<,©¨+DaûäôÒºC÷ Z?EÑèèè7n¨¸hê2™lݺuîîî±±±{öìÉÈÈ€:Ü ]„D"‰‹‹;}úô?ÿü#•Jƒ‚‚Æ?yòd³.´r®P¦ðøéÔX?‡í“C4ÅaÛ®&W ÜÆ}B ½ÿAj@ÃÐÂsçzÓî.¥¹ò_v&åpJAÞš‰š9…^9 ›6mÚ‰' @055-))¡ÓégΜY±bEuuõ÷ß¿hÑ"x÷àî€.BGGG=¯@IIÉÎ;uuu—-[æààðñÇ?~\ àÝà{°îÚc©Bõó˜@MåLFѧå–ý‚!|hѲ_Hb!çȃæKÿ•£ˆÂ/W2ÞtÔâÅ‹;¦P(Á0ŒÇã­\¹2""bâĉ}úôÉÊÊZ¾|9$€# «a±X³gϾqãFSSÓÉ“'õõõgÏžmll¬~|P]]wƒÿ§Q¼ùVÖwÃýŒuiêŠH¦\x⾉«+ÃÚ¦õcÁ{¡oiÁr÷øòL _*WW è”Gúÿuç©æ1AK¿þúëŽ;T*•¦¢T*wìØ¡¯¯ÿôéÓ#GŽØÛã¼@—¥«««¾7PSSsîÜ9''§~øÁÚÚº“¦_¯f°ôéši‚üvõQƒLa„cWÝuß¾"¶:¶ùÒÎ@;¦þšK/ß Ø¼yó?þˆ¢èKu¹\Þ³gOOOÏÞ+íc@7Âãñ.\¸pæÌ™¸¸81vìØÈÈHS­Ÿ_/¯ºÑ{ÔŸx2 IDATÕé=SMvSWJêî?2ïÝÇÌ×ßÞº›ÚgÏ8ÉIÙ+?u7¾ŒïÉ4vÔÞÛY?}êeùü¥Íýû÷Ïœ9óMÿºêèè”””t¥Ñ* ó‚; a2™ŸþùåË—¹\nLL ‚ .´´´4hЦM›´y¾u×;˜Dõmž;võ¥ ª¾¾©—7Ž]uO,wC£•-n|êïäfnøóå畳gÏΚ5«•OP*•k×®ý°]Ð>p'tkJ¥2%%åôéÓgΜáp8ŽŽŽ‘‘‘‘‘‘ƒ&“Éxw÷\yƒÐyʼn]Qf„<_BþYU£ÏšÓCÂŒ»û ʸh,--ºq=cÅ'~¶&êʱÔÂèýñyk&Vd‡……ÉåòWh*•ZTT3ÜAAEÑGÅÆÆž>}:''‡Åb >|üøñ4 ßÞ¾:}ÿLz1û×IšI‚Ç^Úè6îS¦ÄIÁùs,t/-¦ÞT¡˜ûO'ýõ¤W~](‘H4 €L&S(¹\®Èb±<<<¼¼¼ÜÜÜÆŒËÜAàeçÏŸ¿páBVV“É5jTdddDDƒÁèøfÅr»ïŽþ0Âÿ›a=Õ•‚š&÷ŸN9 „S~‹‹‹ânfýô©S]YyøÊÏs&bÒçUÑétGGGOOOwww777777\þÐ m¹á €öð÷÷÷÷÷_³fMQQÑùóç/^¼8yòd"‘8hРQ£F5ª#—1<ü ŰYý=4•õ7ë2˜ÎÎÖx•‘ƒ£¾1ó·k™Çf„""‹+.P=ƒ‡‡ô^4.ÔÕÕÕÖÖïhÜ  mb±øÖ­[—.]ºté‡Ãqppˆˆˆ5jÔ‡~X€aˆ×ªSƒÜ,wE PW¸|±ÝwÇ-ƒú™zy}¸ï Ú£>/¿<áû—Iö&Ï×úûêôýó™%…¿Ljs5´¼@ÛÔSÄÄÄ”——§¥¥Í›7ïéÓ§cÆŒa2™‘‘‘»wﮪªjÿ§Ý¹s§³$±¹¹ÜÆÙý›ß)ß›˜G$“M\ÝÞúgïÓÅ™ªCIÈÑTæ ð,©ÜÊí¾‹\ƒNBoH$,_¾<11±ªªjçÎ:::K—.µ±± \µjUzzz›w×~ýõW‹/¶ùíö%åõ´1 °g©7U(¶ýnŽ‘»‘òðG ‘Œ< @Kø ÌÌÌÔ ***Ž?îååõ×_ª—–×ì¦R©0 Û¹s§ŸŸ_VV–¦.Sª®<)ÿ4ÀQS9—Y¬Ä0ã|;´‡‘£#H<•ÎÖT>õwº‘S!’)qì €v‚À‡ehh8a„C‡q¹Ü£G644¼ºR©d³ÙëÖ­SO6w7¿J “õsÐìs,µÈÐÆšD£vXç =ˆd2ÃÎîhjó¥ÿèžör•*.·Ç®h't‰TSS£yð…B¡P(¾ÿþûðððÊÊÊ«Ùå=¬M,ºê¯ŠdÊø¼J†ƒãkø2tp¼Ïæ6ˆŸ?0Ö¥õv0½š]ŽoW´„:ÎåË—ÕsÈ¿ Š¢ =zô8sþâGÞÍSÎÝÊ­T¨PC;ûß#xk ;[ A®?m¾ôæe{å „Ð @ ƒ¨_|íârd2™F£Ñh4 …‚¢(Ç«8¾.çô_b±X½Ãµ§å¦,²½c[íB¢Pf×ršÏúážÖå Bv-Ç®h˜r€rçι\N$uuu †¡¡¡‘‘“É4111lÁÈÈ(³Z¼>>õwS4C¯æTêÚÀ@í¥kms-ç™f³¯£™.•œPÀu6…ƒ€Vƒ@2dˆP(ÔÓÓksϤSÉ~Œ^=¼Õ›UMâ’Ú&×>°ö¼ö2°²Ê{˜VTÇwb1¡ˆö¬ä"îô`˜àh5x@¡ÓéíI‚Üg×ôu4Ól&³« D‚ž™Y+‡|é±LÉdRRaó’ýœÌï³kpl €ö€€vQ¢èãŠú—B€ “ô†× €6 Hz,Ó$6WSéëh–SÕ³-!íò¬ªQ¦Tõ´1ÑTRJj©,¸  í覦)%ušÍž6&(†=©äáØm‚€vɪàQÉDOK#õ&†!Yõº&&­p§cb’Ãá)ÿ}ûÉÅ`ЩY•õøv@ë  ]²9¼+GêÎïçg¢2 ÕÜÖ(ôcË+Hú†oúÌVö×<hùD kÏ7jO«ƒL§5‰e†‚ L=‘@PÿNÐNÐ"<‘ŒF&éÑžÿÅT¨P±\N¦wtP6ÕçÏ(¯©@•ˆjÏîR4¼8 >†ÿøïÚ1MAVÁ®>´ŸxÅ}2Iï•¥óÞvÿvØv«ˆL§«P´I"7Ò¥"B$Œt©<‘ ¯~h<@‹Hä**I³)’)1 !vøªÕ×Ëk*¨–ön»ïôº'p‹‰礵ܡîÂ^Þµc3k§µ§zÆÕöJ{ìKÖóê-)zÊÝ÷Û«Øæþš‹þ€4Ló_{l³ÕŽD"SÉšŠ.•,QÀò@{A@‹ÈU**©9È”*AˆÄŽþ{Úxï"‚ v_ÿià?ˆ¨«o0ØvÙÖ–;Ô߃ ˆÓ¯ÇÃÇ“XDšŽ^~Ž¿Ÿ@¤!þŸW?ðm÷oÿm¶Ú‘$òïoMJ"µÜ@ÛÀã´ˆL©¢’›Oùr• A‘ôæ#>LœbAô{ ÐT üµÜARøAü¹CÁ Aà CDÎ)yõßvÿöØf«‰@"""S š Bl¹ €¶€Q¨Ð–wäJAB‡ß h†!‚¡¯¹ÆÅ”ŠW‹o½ÿ»ˆu\SG75 ‰Ørm!-B"5ËÐ!B&Á°Ž¾”¤Y9JKr… Fª+‚Œ»-w ;{‹sÒ<¥êyõn϶kÁ0L¥$Èí?°ÍV;Š"ÿþÖÔT(FÖ À¿àO'Z„F!ª¯þ5›‚`ªŽFG#R¶a‘ ã.* Òï”ÿ±¤åfŸÎG„ýåèºó{äœT&Áä2iY~ݹ¿sg¿úíÙŸllŠ HCÜiT.mÿm¶Ú‘PE„F~aTGËM´ Ü @‹PI¤–wÕ^{3üƒ2Ÿö ïÚ1yUiþœÁêŠQèÇrn™f“ÑŸ‹óÕœü³ô—ÙíùÀöìo2¢>ö@ñŠ)šJ@Öæm¶Ú‘0• ù7º©ÉhËM´ üé@‹ÐÈ/ &W¿.ˆvøCe²¡‰Ûž{FGuôÈ &kÜlÇ5‡_ÚÇöëmn;âŒÃ>¥˜YÈ"MGÇÉÛ<ê+¯c™¯ýÌ6÷·]ºÅôÓÿQ-í dJûlO«U*¡“›/®àNÐr –¸@k\x\2vÇ Ù_³4ïÐì³ÐßÄÕ ßÆ@{4ÇÅÉwÌúw0B[°çÀôÁSú¸àݯwÐ"&z/Ï6o¤OSJaÞÙÎA)•éÓiš‘€|©\¡BÕ¿S´„´ˆzÕ€–³Í3õèJ)Ì;Û9¨¤R¦>M³ùêJhhõUc­ 9Xê(Ä¢7´ˆ\,²2l^Zý{4i Ð6Ð",}º.•\R/ÐT\M¨@ÐÊ!@{(ùWVóbH%õ‘`m¤‡cK´BZ„@@L JyÍg}9„€NB)8² 4›%õc= þ™Ú þt ]L Šë^b‘ƒ©gµ†IÂB@ÐÁÄ •#À„´‹K¿¨¶9øXc(&ilı%ÐR>_©TúX15•¢:>„ å  ]|­™Y•õšù;ÜÌ ©d’„WkS mH$xYi*Y<_kf+‡€;h—ž6&©B36L$ºYKx<|»m’ðxö,†åùt5 —/îic‚oW´BÚÅךI$²*›/ýì˜òú:[í!«« °m>ågUð´„´‹>âdjð¨¬9 p±pk:~-Að0LT]5ÐÕBSÈ(«³4Ô55€™‚€Vƒ€Ö q¶H,ä¶ÜT*•b Å$2©<Ĺ9$rû»X´rÚBZ'ØÙ<¥¸Z‰>¿ôw77bèÒDÜj|»­q¹:Tr›çÃ1 IfW·Ìh'h Gs‘Lù”Ó Þ$a^Ö¢Ê2|»­V”‡º[k–ʯi¬IƒœÌðí €6A@ëøX³ôéqÏ*5•áÞ¶|N•z¹z m0*¨¬îc£©Ä=«dЩþv,» =  uˆÂGÞ¶—²š/ý‡zÚ¨T*a·•£^D55r¹"«9\~RáeíFÐFÃ}l“ØÜ&‰\½ic¬çcÍj,)Æ·+ðZ %ÅNfF®f†êM±\ŸÇîc‹oW´„´ÑPOŠÝÊm~"0µ¯3¿¨^Ô6† Øìè¾ÎšÊÝü*™RÕòÆZ BÚÈÔ€>ÈÍòd[S™ÔÛY.—ñ++pì ¼JÈ©’ˆÅ“z7‡€“iì GscXAtÐRãœ.e•‰dÏÚë8˜5° ñí ¼¤¡¨ÐÓšénþ|É™RuáqÉø'|»   ¥>õw’+Ñ+ÙÍÃç ðh,*RJ¤8vZR)ä……ÿà¡©ÜÌ©l’È!€ÎBZÊÔ€>ÀÕâøÃæKÿI.t2™WX€cW ¥†B6A¦öuÓTŽ¥³Љ@@{ÍèyñqiO¨ÞÔ£‘Ç86æç!XëÇÒ˜Ÿ7º§½‘.U½Y#œ}T4g€'¾]Ð~Ð^ãüMôè’ó5•¯Â}…<^S̈?A§©ºæë¡=4•Ã)ºTòÄÞð,tÐ^T2qJ—÷óTèók_kf¨‡M]V¾Ajgõs¶èí`ªÞÄ0d_RÞø' ߯h?hµÿ ò*­žÏ,ÑT¾ ÷i¬äˆëëðk Ò††Æò²eC}5•kOËsª öƱ+Þ„´š›¹áX?‡µ×25•áÞv>6&Õéé8v¸鮿Æcý4•µ×2‡ûØö´1Á¯)Þ„´Ý’0Ÿ´ÒÚdöó¥„ dý¸>¼’RaU¾u[¢Ú^QÑÚ±½‰‚º’QVw¯ jI¨oë m  íºZöu4[s¹ùÒÿ#o[{³šÌG8vÕÕ¿ôw37ü*Ì·:=M.áÛ[7¡Hª¦. ë¡Y.H‰¢ O$Žêa£@'!€Ncãø ª&ñλ͗þkF:2õ+ïÝñ«îƒ“”hk¨³ztóEÿžÄÜ¢ZÁ– Á8vÀ»€@§ak¬¿pˆ÷¯WÕ Ÿ/$H#“vLi¨(o(.··.¯©¬¬®¨xûÄ`™¤®4Šå«c3æôt6eàÛÿ„:“FøëRÉ_œJÖTB=¬æôâ$$*DbëÚ”)çÞ½è~nü›oû}6AU‘0tbèL è”ÓK-üçQ±¦¸eB?–^Y|†Áò‚†”Åß¶fPwN鯩]{Z¾'1wÇ”þƺ4[àA “ânÕÇuÉÉäF±\]¡‘IG?"®©­ÎzŒoo]RÍÓl~çèçCt©ÏWÊ 'ôµ×Ë×ÖxWè|¶Lì‡bؼ£ šJæÖ‰ýª>äWVâØX×#¬ârRR6|ÜW³Z ‚ ‹O$óD²Qý[9€NB‰ýĬð3E'äjŠózMïç^z리‰co]‰L (¹y}J—/Û8ú ðÀý¼£3Cmõqì €÷BÒW‹Å¡>ËΤÖ4ŸòÿœìÂÔ/»¡RÈqì­k@ʲ[q6 úöÉÍo–Ö HšÝßs¸-޽ð¾@ ³ú}\3Æ'17Är¥º¢K%ß\2•—\»Ó ¿ CKânR%¢¸/F0èTuQ¦T}sÓÚHoó„~ø¶Àû!€ÎŠF&ŸQÕ$žqð®¦he¤;?BV_Wžœ„À»ÿUåýqUÕÅùCL 4Å™‡î× .-üH3B€ÎB˜­±þ¾èÁ§ÒÙÛãŸjŠþv¬æ…7äW¦¦àØ[çÅIO«ËÉ91;´Ÿ“¹¦¸7)÷Xjáî©ìM`(è:H«V­Â»ÀçfnH@ߟèÀr53T]Ì ýlLö_MQÊd [xzýªÒ3j=:5'l\/GMñVnåä=·—ó[8ÄÇÞxï Ðé r³¬J¾ûça˜‡µ±žºènadÏÔ?v3Ã0++|;ì,¸W¥=Ü>9$:ÈMS|\Q?lë•I½]¶M‚5@WC€)Æè*tÔökO9 _vd5?ÆÞŸœ7ëð=Soo› `„€cƒçáCnæ£?'…,Ü|¹_Ñ °á¢ƒ‰Áµ%Ã5«Ðe@ ‹Há›/× ¥÷¾Ž´6ÒÓÔO¦±£öÅ»¸Ø H Â0 ×À0¬<)©>÷ÙÞ©ƒ¦7ߨHnˆÕ¡’⿊4Ò¥âØ!„ºžH6xc¬B…Þ]if £©_Ê*¿;NÇÂÂ>|(‰BÁ±C-„*•¥·o **ŽÏ ýÄ¿y@ƒX6dã%©BuïëþgЕ@ KáòÅ7Ä’I„¸/FYéjêŠkFl¿¦¤ëÙûˆª§×Ê't+ ‰¸ôú Lл b «¥¦^# Ûz¥Q,Oøz´f˜]„ºžH6âÏ«UMâ¸/GjÞ@¤ ¦)bÛU®Ha®oiÙÊ't¢êêÒ[qL*áÆâá^–Æš:»–¾ù²¡õÚ’á ÝV>€ÎB]:pÅW÷¶j>½5ŠåŸí¿š]nÝ7ÈÌ×ÇqWû,§29yˆ›ÕñY¡,}º¦žWÝ8|ÛUc]ÚÕÅÃá)èò Ð5 eŠOvÝL-©93wh˜‡µ¦ŽaÈï×ýx1ÍÈÎÎvà 2ÞʇtI*™¬<1WTüÈ^«"ˆ„æ·&îTÛy£§É¹ÿEêÀH@ÐõA ËR¨ÐyG§ìŠ0#Ľå— ¹Qûâë¤*ëAƒ66xuØñUU•wâ IÈ‘ƒ‡¸¿0}ÂÑ…3Ýà´7z• ¯Q€nB]Ü/W2~º˜¶`°÷ÆOûµ<·ñ¥ò…'’¤ä›¸ºY÷ "ëtñ[J™ŒóàA]^î„—]Qý[¾ò§DÑågS7ßÊZ1ÜÍè@L¨º t}מ–OÙsÛÁÄà켡-§B$6«tΑÄF™Ê¼o–›;Ò%O€R_˜_ýà>‰°+*äãó#RZ/ü$æ»–dFèH_;¼zèr¹ãvÞà‰dû¦ zéT×(–/=“²?9WŸej¬onþ¦éŒDµµœä$AMMT_×­‚™z´–_½‘S1ýÀ}åŸÿ õ±bâÕ$x@w!*æK<šZ0÷†OûêP^X÷AqÍ¢“Éi%5LgË€@š!¯>ß¹@P•ž^_PàgËÚ6±_‹–_•)UßKÝrëÉ„ç˜ÏÀ0@Ð=A {9ú pþ±DkcÝ=S;¿pÑaȉ´ÂïÎ¥U4Yîîfþ½¨zrÙ\…HÌĮ́Ï͵4ÔýetàÔ Wâ‹9RKjfºW\'Ø6)øó`÷7}]„ºâ:Á¬ÃwïäUÍìõÛØ>ô&F1ìlFñòóKjù†v¶¦>¾ kë7}”¶UWs35••Û³ëÇõþÄßñ¥Ó¿H¦üáÂÃ?ã³Cœ-öDl9™Ý„º# CÞÏ_v&E—JþãÓ  N/í W¢‡䯿‘•Ïm4²²bz{Ù;híúC†5••òžæ4VV8² ¿‰è1­Ÿòò¢ÿ<*^z:¥I"_ÿIß™!]r$oBÝW­@úí¹’ó¸ZlÜÓÆä¥0 ¹ü¤lã­'wó8t=#wW7C‹† È‚ú‚Æg¹‘0ÄÅê«0Ÿ1~öÄWNïÙÞ'ïÇçq¦¹®ý¸L €„º»Gåu_žºŸXÈêãúÃÈ^¯½C^R/8œÿwr‡'d°LôítLpN/mhh()–ókëÌôf»}ìîlúštR\'øùrÆá”‚¾Žf›'ôëí`ÚñÝ µ AÎg–üx!-—ÛøYËŠáþ.f¯9¡b’R\}*­èxzQu£H¡¯gkǰ³Ó·° Q>øèz•B!âr›ÊÊDe¢&‹¡;)Àib S°³ù«—þ‚Õñ¿šyð~¾‹cÍèÀOz9Áý^!ðŠa'ÓØ«bÓ køcüì—íâlñ¦=3Êê®<)¿ø¤,£´–@@ ˜Lª¹…ž©©Ž1“nlD$“_{àÛõ£RJ% âšZY WP_aHO[Öè¶#|ìz;˜¾öÜ HjIÍ7²þyTì`b°rTÀ”>.$"œÿx €¨PìlFñú™é¥u}ÍæöàôÒ¤-ñD²ûEÕ÷‹ªã ª3ËêÄ29@ÐcP ²>ƒÊ0 êë‘it2N¦ÓIT H$Rž¿€*”ªRÉJ¹T)•*¥2…P$ð•RÀòùŠéÒ(¾¶&C\,‚Íû9™·\ñï%2¥êlFñλ9‰…Üž6&ß ë9!Љ¬­ƒÐ¯w+·rÛíì«Ùåú4Jt?×σÝ_9ø CŠêø™åõÙ»–_P+(®Ô4‰Ûùï €°ºN& WS'S_k¦Ÿ ËÉÔàMWüÙÞäüƒ÷óIJa^¶‹C}"¼làæ?m‚hM5_r4µà@rþ“Jž»¹Ñ„@§ñN¾Öo7$'’ñD²z‘T UÈU*‘L©®ëRÉ42É€Naêјz4½·[Ä(§ªátzÑ©´¢œªOK£éýÜ?ëëje#ÿh/€vɪàXxâ!»¤^`k¬áeáeæiõ¶gîwÔ –ÝÎåÜÈ©¸‘S¡îdbo§)}\zÙ²:² º€·€aÈÃÒšËOÊ®<)Ï(«ÃÌËÒ8ÄÙ¢¿‹EoSW3Ã÷>O…bìZþÃ’Ú$67¡€›SÕ€!X/[ÖpÛ‘¾v}ÍÚ|Xx€ÿ¨F ¹ËIfW'q—ó”(J§¼,}­™îæFΦ 3†³)ã­ÖæáKåìZ>»–_ÍÂò¡åIDATXÃϯnzRÉ{Êi(”$"Áךâlìl>ÄÝÊÒîùð@¼B™"»²áI%/›ÃËæðŠë "… E„J&ëÒ˜z4c]š.õ5oHä*žXÚ ’7ˆe2¥ A ‰hm¤çÈ2ð¶2öµfúX1}­™/­qxwŠaUMâ’zAPZ×V ÄuB©D®’*TÅót I‡B¦SH,}º9CÇÌ@ÇÔ€nÏ4°4Ô…7ûè€n ¦Ñº)@7!è¦þ‹] ½nI!ˆIEND®B`‚glance-2014.1/doc/source/glanceapi.rst0000664000175400017540000006135612323736226020733 0ustar jenkinsjenkins00000000000000.. Copyright 2010 OpenStack Foundation All Rights Reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Using Glance's Public APIs ========================== Glance fully implements versions 1.0, 1.1 and 2.0 of the OpenStack Images API. The Images API specification is developed alongside Glance, but is not considered part of the Glance project. Authentication -------------- Glance depends on Keystone and the OpenStack Identity API to handle authentication of clients. You must obtain an authentication token from Keystone using and send it along with all API requests to Glance through the ``X-Auth-Token`` header. Glance will communicate back to Keystone to verify the token validity and obtain your identity credentials. See :doc:`authentication` for more information on integrating with Keystone. Using v1.X ---------- For the purpose of examples, assume there is a Glance API server running at the URL ``http://glance.example.com`` on the default port 80. List Available Images ********************* We want to see a list of available images that the authenticated user has access to. This includes images owned by the user, images shared with the user and public images. We issue a ``GET`` request to ``http://glance.example.com/v1/images`` to retrieve this list of available images. The data is returned as a JSON-encoded mapping in the following format:: {'images': [ {'uri': 'http://glance.example.com/v1/images/71c675ab-d94f-49cd-a114-e12490b328d9', 'name': 'Ubuntu 10.04 Plain', 'disk_format': 'vhd', 'container_format': 'ovf', 'size': '5368709120'} ...]} List Available Images in More Detail ************************************ We want to see a more detailed list of available images that the authenticated user has access to. This includes images owned by the user, images shared with the user and public images. We issue a ``GET`` request to ``http://glance.example.com/v1/images/detail`` to retrieve this list of available images. The data is returned as a JSON-encoded mapping in the following format:: {'images': [ {'uri': 'http://glance.example.com/v1/images/71c675ab-d94f-49cd-a114-e12490b328d9', 'name': 'Ubuntu 10.04 Plain 5GB', 'disk_format': 'vhd', 'container_format': 'ovf', 'size': '5368709120', 'checksum': 'c2e5db72bd7fd153f53ede5da5a06de3', 'created_at': '2010-02-03 09:34:01', 'updated_at': '2010-02-03 09:34:01', 'deleted_at': '', 'status': 'active', 'is_public': true, 'min_ram': 256, 'min_disk': 5, 'owner': null, 'properties': {'distro': 'Ubuntu 10.04 LTS'}}, ...]} .. note:: All timestamps returned are in UTC The `updated_at` timestamp is the timestamp when an image's metadata was last updated, not its image data, as all image data is immutable once stored in Glance The `properties` field is a mapping of free-form key/value pairs that have been saved with the image metadata The `checksum` field is an MD5 checksum of the image file data The `is_public` field is a boolean indicating whether the image is publicly available The `min_ram` field is an integer specifying the minimum amount of ram needed to run this image on an instance, in megabytes The `min_disk` field is an integer specifying the minimum amount of disk space needed to run this image on an instance, in gigabytes The `owner` field is a string which may either be null or which will indicate the owner of the image Filtering Images Lists ********************** Both the ``GET /v1/images`` and ``GET /v1/images/detail`` requests take query parameters that serve to filter the returned list of images. The following list details these query parameters. * ``name=NAME`` Filters images having a ``name`` attribute matching ``NAME``. * ``container_format=FORMAT`` Filters images having a ``container_format`` attribute matching ``FORMAT`` For more information, see :doc:`About Disk and Container Formats ` * ``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 additional query parameters: * ``sort_key=KEY`` Results will be ordered by the specified image attribute ``KEY``. Accepted values include ``id``, ``name``, ``status``, ``disk_format``, ``container_format``, ``size``, ``created_at`` (default) and ``updated_at``. * ``sort_dir=DIR`` Results will be sorted in the direction ``DIR``. Accepted values are ``asc`` for ascending or ``desc`` (default) for descending. * ``marker=ID`` An image identifier marker may be specified. When present only images which occur after the identifier ``ID`` will be listed, ie the images which have a `sort_key` later than that of the marker ``ID`` in the `sort_dir` direction. * ``limit=LIMIT`` When present the maximum number of results returned will not exceed ``LIMIT``. .. note:: If the specified ``LIMIT`` exceeds the operator defined limit (api_limit_max) then the number of results returned may be less than ``LIMIT``. * ``is_public=PUBLIC`` An admin user may use the `is_public` parameter to control which results are returned. When the `is_public` parameter is absent or set to `True` the following images will be listed: Images whose `is_public` field is `True`, owned images and shared images. When the `is_public` parameter is set to `False` the following images will be listed: Images (owned, shared, or non-owned) whose `is_public` field is `False`. When the `is_public` parameter is set to `None` all images will be listed irrespective of owner, shared status or the `is_public` field. .. note:: Use of the `is_public` parameter is restricted to admin users. For all other users it will be ignored. Retrieve Image Metadata *********************** We want to see detailed information for a specific virtual machine image that the Glance server knows about. We have queried the Glance server for a list of images and the data returned includes the `uri` field for each available image. This `uri` field value contains the exact location needed to get the metadata for a specific image. Continuing the example from above, in order to get metadata about the first image returned, we can issue a ``HEAD`` request to the Glance server for the image's URI. We issue a ``HEAD`` request to ``http://glance.example.com/v1/images/71c675ab-d94f-49cd-a114-e12490b328d9`` to retrieve complete metadata for that image. The metadata is returned as a set of HTTP headers that begin with the prefix ``x-image-meta-``. The following shows an example of the HTTP headers returned from the above ``HEAD`` request:: x-image-meta-uri http://glance.example.com/v1/images/71c675ab-d94f-49cd-a114-e12490b328d9 x-image-meta-name Ubuntu 10.04 Plain 5GB x-image-meta-disk_format vhd x-image-meta-container_format ovf x-image-meta-size 5368709120 x-image-meta-checksum c2e5db72bd7fd153f53ede5da5a06de3 x-image-meta-created_at 2010-02-03 09:34:01 x-image-meta-updated_at 2010-02-03 09:34:01 x-image-meta-deleted_at x-image-meta-status available x-image-meta-is_public true x-image-meta-min_ram 256 x-image-meta-min_disk 0 x-image-meta-owner null x-image-meta-property-distro Ubuntu 10.04 LTS .. note:: All timestamps returned are in UTC The `x-image-meta-updated_at` timestamp is the timestamp when an image's metadata was last updated, not its image data, as all image data is immutable once stored in Glance There may be multiple headers that begin with the prefix `x-image-meta-property-`. These headers are free-form key/value pairs that have been saved with the image metadata. The key is the string after `x-image-meta-property-` and the value is the value of the header The response's `ETag` header will always be equal to the `x-image-meta-checksum` value The response's `x-image-meta-is_public` value is a boolean indicating whether the image is publicly available The response's `x-image-meta-owner` value is a string which may either be null or which will indicate the owner of the image Retrieve Raw Image Data *********************** We want to retrieve that actual raw data for a specific virtual machine image that the Glance server knows about. We have queried the Glance server for a list of images and the data returned includes the `uri` field for each available image. This `uri` field value contains the exact location needed to get the metadata for a specific image. Continuing the example from above, in order to get metadata about the first image returned, we can issue a ``HEAD`` request to the Glance server for the image's URI. We issue a ``GET`` request to ``http://glance.example.com/v1/images/71c675ab-d94f-49cd-a114-e12490b328d9`` to retrieve metadata for that image as well as the image itself encoded into the response body. The metadata is returned as a set of HTTP headers that begin with the prefix ``x-image-meta-``. The following shows an example of the HTTP headers returned from the above ``GET`` request:: x-image-meta-uri http://glance.example.com/v1/images/71c675ab-d94f-49cd-a114-e12490b328d9 x-image-meta-name Ubuntu 10.04 Plain 5GB x-image-meta-disk_format vhd x-image-meta-container_format ovf x-image-meta-size 5368709120 x-image-meta-checksum c2e5db72bd7fd153f53ede5da5a06de3 x-image-meta-created_at 2010-02-03 09:34:01 x-image-meta-updated_at 2010-02-03 09:34:01 x-image-meta-deleted_at x-image-meta-status available x-image-meta-is_public true x-image-meta-min_ram 256 x-image-meta-min_disk 5 x-image-meta-owner null x-image-meta-property-distro Ubuntu 10.04 LTS .. note:: All timestamps returned are in UTC The `x-image-meta-updated_at` timestamp is the timestamp when an image's metadata was last updated, not its image data, as all image data is immutable once stored in Glance There may be multiple headers that begin with the prefix `x-image-meta-property-`. These headers are free-form key/value pairs that have been saved with the image metadata. The key is the string after `x-image-meta-property-` and the value is the value of the header The response's `Content-Length` header shall be equal to the value of the `x-image-meta-size` header The response's `ETag` header will always be equal to the `x-image-meta-checksum` value The response's `x-image-meta-is_public` value is a boolean indicating whether the image is publicly available The response's `x-image-meta-owner` value is a string which may either be null or which will indicate the owner of the image The image data itself will be the body of the HTTP response returned from the request, which will have content-type of `application/octet-stream`. Add a New Image *************** We have created a new virtual machine image in some way (created a "golden image" or snapshotted/backed up an existing image) and we wish to do two things: * Store the disk image data in Glance * Store metadata about this image in Glance We can do the above two activities in a single call to the Glance API. Assuming, like in the examples above, that a Glance API server is running at ``glance.example.com``, we issue a ``POST`` request to add an image to Glance:: POST http://glance.example.com/v1/images The metadata about the image is sent to Glance in HTTP headers. The body of the HTTP request to the Glance API will be the MIME-encoded disk image data. Reserve a New Image ******************* We can also perform the activities described in `Add a New Image`_ using two separate calls to the Image API; the first to register the image metadata, and the second to add the image disk data. This is known as "reserving" an image. The first call should be a ``POST`` to ``http://glance.example.com/v1/images``, which will result in a new image id being registered with a status of ``queued``:: {"image": {"status": "queued", "id": "71c675ab-d94f-49cd-a114-e12490b328d9", ...} ...} The image data can then be added using a ``PUT`` to ``http://glance.example.com/v1/images/71c675ab-d94f-49cd-a114-e12490b328d9``. The image status will then be set to ``active`` by Glance. **Image Metadata in HTTP Headers** Glance will view as image metadata any HTTP header that it receives in a ``POST`` request where the header key is prefixed with the strings ``x-image-meta-`` and ``x-image-meta-property-``. The list of metadata headers that Glance accepts are listed below. * ``x-image-meta-name`` This header is required, unless reserving an image. Its value should be the name of the image. Note that the name of an image *is not unique to a Glance node*. It would be an unrealistic expectation of users to know all the unique names of all other user's images. * ``x-image-meta-id`` This header is optional. When present, Glance will use the supplied identifier for the image. If the identifier already exists in that Glance node, then a **409 Conflict** will be returned by Glance. The value of the header must be a uuid in hexadecimal string notation (i.e. 71c675ab-d94f-49cd-a114-e12490b328d9). When this header is *not* present, Glance will generate an identifier for the image and return this identifier in the response (see below) * ``x-image-meta-store`` This header is optional. Valid values are one of ``file``, ``s3``, ``rbd``, ``swift``, ``cinder``, ``gridfs``, ``sheepdog`` or ``vsphere`` When present, Glance will attempt to store the disk image data in the backing store indicated by the value of the header. If the Glance node does not support the backing store, Glance will return a **400 Bad Request**. When not present, Glance will store the disk image data in the backing store that is marked default. See the configuration option ``default_store`` for more information. * ``x-image-meta-disk_format`` This header is required, unless reserving an image. Valid values are one of ``aki``, ``ari``, ``ami``, ``raw``, ``iso``, ``vhd``, ``vdi``, ``qcow2``, or ``vmdk``. For more information, see :doc:`About Disk and Container Formats ` * ``x-image-meta-container_format`` This header is required, unless reserving an image. Valid values are one of ``aki``, ``ari``, ``ami``, ``bare``, or ``ovf``. For more information, see :doc:`About Disk and Container Formats ` * ``x-image-meta-size`` This header is optional. When present, Glance assumes that the expected size of the request body will be the value of this header. If the length in bytes of the request body *does not match* the value of this header, Glance will return a **400 Bad Request**. When not present, Glance will calculate the image's size based on the size of the request body. * ``x-image-meta-checksum`` This header is optional. When present it shall be the expected **MD5** checksum of the image file data. When present, Glance will verify the checksum generated from the backend store when storing your image against this value and return a **400 Bad Request** if the values do not match. * ``x-image-meta-is_public`` This header is optional. When Glance finds the string "true" (case-insensitive), the image is marked as a public image, meaning that any user may view its metadata and may read the disk image from Glance. When not present, the image is assumed to be *not public* and owned by a user. * ``x-image-meta-min_ram`` This header is optional. When present it shall be the expected minimum ram required in megabytes to run this image on a server. When not present, the image is assumed to have a minimum ram requirement of 0. * ``x-image-meta-min_disk`` This header is optional. When present it shall be the expected minimum disk space required in gigabytes to run this image on a server. When not present, the image is assumed to have a minimum disk space requirement of 0. * ``x-image-meta-owner`` This header is optional and only meaningful for admins. Glance normally sets the owner of an image to be the tenant or user (depending on the "owner_is_tenant" configuration option) of the authenticated user issuing the request. However, if the authenticated user has the Admin role, this default may be overridden by setting this header to null or to a string identifying the owner of the image. * ``x-image-meta-property-*`` When Glance receives any HTTP header whose key begins with the string prefix ``x-image-meta-property-``, Glance adds the key and value to a set of custom, free-form image properties stored with the image. The key is the lower-cased string following the prefix ``x-image-meta-property-`` with dashes and punctuation replaced with underscores. For example, if the following HTTP header were sent:: x-image-meta-property-distro Ubuntu 10.10 Then a key/value pair of "distro"/"Ubuntu 10.10" will be stored with the image in Glance. There is no limit on the number of free-form key/value attributes that can be attached to the image. However, keep in mind that the 8K limit on the size of all HTTP headers sent in a request will effectively limit the number of image properties. Update an Image *************** Glance will view as image metadata any HTTP header that it receives in a ``PUT`` request where the header key is prefixed with the strings ``x-image-meta-`` and ``x-image-meta-property-``. If an image was previously reserved, and thus is in the ``queued`` state, then image data can be added by including it as the request body. If the image already as data associated with it (e.g. not in the ``queued`` state), then including a request body will result in a **409 Conflict** exception. On success, the ``PUT`` request will return the image metadata encoded as HTTP headers. See more about image statuses here: :doc:`Image Statuses ` List Image Memberships ********************** We want to see a list of the other system tenants (or users, if "owner_is_tenant" is False) that may access a given virtual machine image that the Glance server knows about. We take the `uri` field of the image data, append ``/members`` to it, and issue a ``GET`` request on the resulting URL. Continuing from the example above, in order to get the memberships for the first image returned, we can issue a ``GET`` request to the Glance server for ``http://glance.example.com/v1/images/71c675ab-d94f-49cd-a114-e12490b328d9/members`` . What we will get back is JSON data such as the following:: {'members': [ {'member_id': 'tenant1', 'can_share': false} ...]} The `member_id` field identifies a tenant with which the image is shared. If that tenant is authorized to further share the image, the `can_share` field is `true`. List Shared Images ****************** We want to see a list of images which are shared with a given tenant. We issue a ``GET`` request to ``http://glance.example.com/v1/shared-images/tenant1``. We will get back JSON data such as the following:: {'shared_images': [ {'image_id': '71c675ab-d94f-49cd-a114-e12490b328d9', 'can_share': false} ...]} The `image_id` field identifies an image shared with the tenant named by *member_id*. If the tenant is authorized to further share the image, the `can_share` field is `true`. Add a Member to an Image ************************ We want to authorize a tenant to access a private image. We issue a ``PUT`` request to ``http://glance.example.com/v1/images/71c675ab-d94f-49cd-a114-e12490b328d9/members/tenant1`` . With no body, this will add the membership to the image, leaving existing memberships unmodified and defaulting new memberships to have `can_share` set to `false`. We may also optionally attach a body of the following form:: {'member': {'can_share': true} } If such a body is provided, both existing and new memberships will have `can_share` set to the provided value (either `true` or `false`). This query will return a 204 ("No Content") status code. Remove a Member from an Image ***************************** We want to revoke a tenant's right to access a private image. We issue a ``DELETE`` request to ``http://glance.example.com/v1/images/1/members/tenant1``. This query will return a 204 ("No Content") status code. Replace a Membership List for an Image ************************************** The full membership list for a given image may be replaced. We issue a ``PUT`` request to ``http://glance.example.com/v1/images/71c675ab-d94f-49cd-a114-e12490b328d9/members`` with a body of the following form:: {'memberships': [ {'member_id': 'tenant1', 'can_share': false} ...]} All existing memberships which are not named in the replacement body are removed, and those which are named have their `can_share` settings changed as specified. (The `can_share` setting may be omitted, which will cause that setting to remain unchanged in the existing memberships.) All new memberships will be created, with `can_share` defaulting to `false` if it is not specified. Image Membership Changes in Version 2.0 --------------------------------------- Version 2.0 of the Images API eliminates the ``can_share`` attribute of image membership. In the version 2.0 model, image sharing is not transitive. In version 2.0, image members have a ``status`` attribute that reflects how the image should be treated with respect to that image member's image list. * The ``status`` attribute may have one of three values: ``pending``, ``accepted``, or ``rejected``. * By default, only those shared images with status ``accepted`` are included in an image member's image-list. * Only an image member may change his/her own membership status. * Only an image owner may create members on an image. The status of a newly created image member is ``pending``. The image owner cannot change the status of a member. Distinctions from Version 1.x API Calls *************************************** * The response to a request to list the members of an image has changed. call: ``GET`` on ``/v2/images/{imageId}/members`` response: see the JSON schema at ``/v2/schemas/members`` * The request body in the call to create an image member has changed. call: ``POST`` to ``/v2/images/{imageId}/members`` request body:: { "member": "" } where the {memberId} is the tenant ID of the image member. The member status of a newly created image member is ``pending``. New API Calls ************* * Change the status of an image member call: ``PUT`` on ``/v2/images/{imageId}/members/{memberId}`` request body:: { "status": "" } where is one of ``pending``, ``accepted``, or ``rejected``. The {memberId} is the tenant ID of the image member. API Message Localization --------------------------------------- Glance supports HTTP message localization. For example, an HTTP client can receive API messages in Chinese even if the locale language of the server is English. How to use it ************* To receive localized API messages, the HTTP client needs to specify the **Accept-Language** header to indicate the language to use to translate the message. For more info about Accept-Language, please refer http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html A typical curl API request will be like below:: curl -i -X GET -H 'Accept-Language: zh' -H 'Content-Type: application/json' http://127.0.0.1:9292/v2/images/aaa Then the response will be like the following:: HTTP/1.1 404 Not Found Content-Length: 234 Content-Type: text/html; charset=UTF-8 X-Openstack-Request-Id: req-54d403a0-064e-4544-8faf-4aeef086f45a Date: Sat, 22 Feb 2014 06:26:26 GMT 404 Not Found

404 Not Found

找不到任何具有标识 aaa 的映像

.. note:: Be sure there is the language package under /usr/share/locale-langpack/ on the target Glance server. glance-2014.1/doc/source/db.rst0000664000175400017540000000327212323736226017366 0ustar jenkinsjenkins00000000000000.. Copyright 2012 OpenStack Foundation All Rights Reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Database Management =================== The default metadata driver for glance uses sqlalchemy, which implies there exists a backend database which must be managed. The ``glance-manage`` binary provides a set of commands for making this easier. The commands should be executed as a subcommand of 'db': glance-manage db Sync the Database ----------------- glance-manage db sync Place a database under migration control and upgrade, creating it first if necessary. Determining the Database Version -------------------------------- glance-manage db version This will print the current migration level of a glance database. Upgrading an Existing Database ------------------------------ glance-manage db upgrade This will take an existing database and upgrade it to the specified VERSION. Downgrading an Existing Database -------------------------------- glance-manage db downgrade This will downgrade an existing database from the current version to the specified VERSION. glance-2014.1/doc/source/man/0000775000175400017540000000000012323736427017021 5ustar jenkinsjenkins00000000000000glance-2014.1/doc/source/man/glancemanage.rst0000664000175400017540000000331412323736226022153 0ustar jenkinsjenkins00000000000000============= glance-manage ============= ------------------------- Glance Management Utility ------------------------- :Author: glance@lists.launchpad.net :Date: 2014-01-16 :Copyright: OpenStack LLC :Version: 2014.1 :Manual section: 1 :Manual group: cloud computing SYNOPSIS ======== glance-manage [options] DESCRIPTION =========== glance-manage is a utility for managing and configuring a Glance installation. One important use of glance-manage is to setup the database. To do this run:: glance-manage db_sync Note: glance-manage commands can be run either like this:: glance-manage db sync or with the db commands concatenated, like this:: glance-manage db_sync COMMANDS ======== **db** This is the prefix for the commands below when used with a space rather than a _. For example "db version". **db_version** This will print the current migration level of a glance database. **db_upgrade ** This will take an existing database and upgrade it to the specified VERSION. **db_downgrade ** This will take an existing database and downgrade it to the specified VERSION. **db_version_control** Place the database untder migration control. **db_sync ** Place a database under migration control and upgrade, creating it first if necessary. OPTIONS ======== **General Options** .. include:: general_options.rst **--sql_connection=CONN_STRING** A proper SQLAlchemy connection string as described `here `_ .. include:: footer.rst glance-2014.1/doc/source/man/glancecachemanage.rst0000664000175400017540000000366612323736226023151 0ustar jenkinsjenkins00000000000000=================== glance-cache-manage =================== ------------------------ Cache management utility ------------------------ :Author: glance@lists.launchpad.net :Date: 2014-01-16 :Copyright: OpenStack LLC :Version: 2014.1 :Manual section: 1 :Manual group: cloud computing SYNOPSIS ======== glance-cache-manage [options] [args] COMMANDS ======== **help ** Output help for one of the commands below **list-cached** List all images currently cached **list-queued** List all images currently queued for caching **queue-image** Queue an image for caching **delete-cached-image** Purges an image from the cache **delete-all-cached-images** Removes all images from the cache **delete-queued-image** Deletes an image from the cache queue **delete-all-queued-images** Deletes all images from the cache queue OPTIONS ======= **--version** show program's version number and exit **-h, --help** show this help message and exit **-v, --verbose** Print more verbose output **-d, --debug** Print more verbose output **-H ADDRESS, --host=ADDRESS** Address of Glance API host. Default: 0.0.0.0 **-p PORT, --port=PORT** Port the Glance API host listens on. Default: 9292 **-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, --auth_token=TOKEN** Authentication token to use to identify the client to the glance server **-f, --force** Prevent select actions from requesting user confirmation **-S STRATEGY, --os-auth-strategy=STRATEGY** Authentication strategy (keystone or noauth) .. include:: openstack_options.rst .. include:: footer.rst glance-2014.1/doc/source/man/glanceregistry.rst0000664000175400017540000000125612323736226022576 0ustar jenkinsjenkins00000000000000=============== glance-registry =============== -------------------------------------- Server for the Glance Registry Service -------------------------------------- :Author: glance@lists.launchpad.net :Date: 2014-01-16 :Copyright: OpenStack LLC :Version: 2014.1 :Manual section: 1 :Manual group: cloud computing SYNOPSIS ======== glance-registry [options] DESCRIPTION =========== glance-registry is a server daemon that serves image metadata through a REST-like API. OPTIONS ======= **General options** .. include:: general_options.rst FILES ===== **/etc/glance/glance-registry.conf** Default configuration file for Glance Registry .. include:: footer.rst glance-2014.1/doc/source/man/general_options.rst0000664000175400017540000000454512323736226022750 0ustar jenkinsjenkins00000000000000 **-h, --help** Show the help message and exit **--version** Print the version number and exit **-v, --verbose** Print more verbose output **--noverbose** Disable verbose output **-d, --debug** Print debugging output (set logging level to DEBUG instead of default WARNING level) **--nodebug** Disable debugging output **--use-syslog** Use syslog for logging **--nouse-syslog** Disable the use of syslog for logging **--syslog-log-facility SYSLOG_LOG_FACILITY** syslog facility to receive log lines **--config-dir DIR** Path to a config directory to pull \*.conf files from. This file set is sorted, so as to provide a predictable parse order if individual options are over-ridden. The set is parsed after the file(s) specified via previous --config-file, arguments hence over-ridden options in the directory take precedence. This means that configuration from files in a specified config-dir will always take precedence over configuration from files specified by --config-file, regardless to argument order. **--config-file PATH** Path to a config file to use. Multiple config files can be specified by using this flag multiple times, for example, --config-file --config-file . Values in latter files take precedence. **--log-config-append PATH** **--log-config PATH** The name of logging configuration file. It does not disable existing loggers, but just appends specified logging configuration to any other existing logging options. Please see the Python logging module documentation for details on logging configuration files. The log-config name for this option is depcrecated. **--log-format FORMAT** A logging.Formatter log message format string which may use any of the available logging.LogRecord attributes. Default: None **--log-date-format DATE_FORMAT** Format string for %(asctime)s in log records. Default: None **--log-file PATH, --logfile PATH** (Optional) Name of log file to output to. If not set, logging will go to stdout. **--log-dir LOG_DIR, --logdir LOG_DIR** (Optional) The directory to keep log files in (will be prepended to --log-file) glance-2014.1/doc/source/man/openstack_options.rst0000664000175400017540000000100512323736226023306 0ustar jenkinsjenkins00000000000000 **-os-auth-token=OS_AUTH_TOKEN** Defaults to env[OS_AUTH_TOKEN] **--os-username=OS_USERNAME** Defaults to env[OS_USERNAME] **--os-password=OS_PASSWORD** Defaults to env[OS_PASSWORD] **--os-region-name=OS_REGION_NAME** Defaults to env[OS_REGION_NAME] **--os-tenant-id=OS_TENANT_ID** Defaults to env[OS_TENANT_ID] **--os-tenant-name=OS_TENANT_NAME** Defaults to env[OS_TENANT_NAME] **--os-auth-url=OS_AUTH_URL** Defaults to env[OS_AUTH_URL] glance-2014.1/doc/source/man/glancecachecleaner.rst0000664000175400017540000000214212323736226023316 0ustar jenkinsjenkins00000000000000==================== glance-cache-cleaner ==================== ---------------------------------------------------------------- Glance Image Cache Invalid Cache Entry and Stalled Image cleaner ---------------------------------------------------------------- :Author: glance@lists.launchpad.net :Date: 2014-01-16 :Copyright: OpenStack LLC :Version: 2014.1 :Manual section: 1 :Manual group: cloud computing SYNOPSIS ======== glance-cache-cleaner [options] DESCRIPTION =========== This is meant to be run as a periodic task from cron. If something goes wrong while we're caching an image (for example the fetch times out, or an exception is raised), we create an 'invalid' entry. These entires are left around for debugging purposes. However, after some period of time, we want to clean these up. Also, if an incomplete image hangs around past the image_cache_stall_time period, we automatically sweep it up. OPTIONS ======= **General options** .. include:: general_options.rst FILES ====== **/etc/glance/glance-cache.conf** Default configuration file for the Glance Cache .. include:: footer.rst glance-2014.1/doc/source/man/glancecontrol.rst0000664000175400017540000000234012323736226022401 0ustar jenkinsjenkins00000000000000============== glance-control ============== -------------------------------------- Glance daemon start/stop/reload helper -------------------------------------- :Author: glance@lists.launchpad.net :Date: 2014-01-16 :Copyright: OpenStack LLC :Version: 2014.1 :Manual section: 1 :Manual group: cloud computing SYNOPSIS ======== glance-control [options] [CONFPATH] Where is one of: all, api, glance-api, registry, glance-registry, scrubber, glance-scrubber And command is one of: start, status, stop, shutdown, restart, reload, force-reload And CONFPATH is the optional configuration file to use. OPTIONS ======== **General Options** .. include:: general_options.rst **--pid-file=PATH** File to use as pid file. Default: /var/run/glance/$server.pid **--await-child DELAY** Period to wait for service death in order to report exit code (default is to not wait at all) **--capture-output** Capture stdout/err in syslog instead of discarding **--nocapture-output** The inverse of --capture-output **--norespawn** The inverse of --respawn **--respawn** Restart service on unexpected death .. include:: footer.rst glance-2014.1/doc/source/man/footer.rst0000664000175400017540000000032312323736226021044 0ustar jenkinsjenkins00000000000000SEE ALSO ======== * `OpenStack Glance `__ BUGS ==== * Glance bugs are tracked in Launchpad so you can view current bugs at `OpenStack Glance `__ glance-2014.1/doc/source/man/glancescrubber.rst0000664000175400017540000000327412323736226022537 0ustar jenkinsjenkins00000000000000=============== glance-scrubber =============== -------------------- Glance scrub service -------------------- :Author: glance@lists.launchpad.net :Date: 2014-01-16 :Copyright: OpenStack LLC :Version: 2014.1 :Manual section: 1 :Manual group: cloud computing SYNOPSIS ======== 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 ======= **General options** .. include:: general_options.rst **-D, --daemon** 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. **--nodaemon** The inverse of --daemon. Runs the scrub operation once and then exits. This is the default. FILES ====== **/etc/glance/glance-scrubber.conf** Default configuration file for the Glance Scrubber .. include:: footer.rst glance-2014.1/doc/source/man/glancecachepruner.rst0000664000175400017540000000135712323736226023227 0ustar jenkinsjenkins00000000000000=================== glance-cache-pruner =================== ------------------- Glance cache pruner ------------------- :Author: glance@lists.launchpad.net :Date: 2014-01-16 :Copyright: OpenStack LLC :Version: 2014.1 :Manual section: 1 :Manual group: cloud computing SYNOPSIS ======== glance-cache-pruner [options] DESCRIPTION =========== Prunes images from the Glance cache when the space exceeds the value set in the image_cache_max_size configuration option. This is meant to be run as a periodic task, perhaps every half-hour. OPTIONS ======== **General options** .. include:: general_options.rst FILES ===== **/etc/glance/glance-cache.conf** Default configuration file for the Glance Cache .. include:: footer.rst glance-2014.1/doc/source/man/glancereplicator.rst0000664000175400017540000000424612323736226023074 0ustar jenkinsjenkins00000000000000================= glance-replicator ================= --------------------------------------------- Replicate images across multiple data centers --------------------------------------------- :Author: glance@lists.launchpad.net :Date: 2014-01-16 :Copyright: OpenStack LLC :Version: 2014.1 :Manual section: 1 :Manual group: cloud computing SYNOPSIS ======== glance-replicator [options] [args] DESCRIPTION =========== glance-replicator is a utility can be used to populate a new glance server using the images stored in an existing glance server. The images in the replicated glance server preserve the uuids, metadata, and image data from the original. COMMANDS ======== **help ** Output help for one of the commands below **compare** What is missing from the slave glance? **dump** Dump the contents of a glance instance to local disk. **livecopy** Load the contents of one glance instance into another. **load** Load the contents of a local directory into glance. **size** Determine the size of a glance instance if dumped to disk. OPTIONS ======= **-h, --help** Show this help message and exit **-c CHUNKSIZE, --chunksize=CHUNKSIZE** Amount of data to transfer per HTTP write **-d, --debug** Print debugging information **-D DONTREPLICATE, --dontreplicate=DONTREPLICATE** List of fields to not replicate **-m, --metaonly** Only replicate metadata, not images **-l LOGFILE, --logfile=LOGFILE** Path of file to log to **-s, --syslog** Log to syslog instead of a file **-t TOKEN, --token=TOKEN** Pass in your authentication token if you have one. If you use this option the same token is used for both the master and the slave. **-M MASTERTOKEN, --mastertoken=MASTERTOKEN** Pass in your authentication token if you have one. This is the token used for the master. **-S SLAVETOKEN, --slavetoken=SLAVETOKEN** Pass in your authentication token if you have one. This is the token used for the slave. **-v, --verbose** Print more verbose output .. include:: footer.rst glance-2014.1/doc/source/man/glancecacheprefetcher.rst0000664000175400017540000000126512323736226024041 0ustar jenkinsjenkins00000000000000======================= glance-cache-prefetcher ======================= ------------------------------ Glance Image Cache Pre-fetcher ------------------------------ :Author: glance@lists.launchpad.net :Date: 2014-01-16 :Copyright: OpenStack LLC :Version: 2014.1 :Manual section: 1 :Manual group: cloud computing SYNOPSIS ======== glance-cache-prefetcher [options] DESCRIPTION =========== This is meant to be run from the command line after queueing images to be pretched. OPTIONS ======= **General options** .. include:: general_options.rst FILES ===== **/etc/glance/glance-cache.conf** Default configuration file for the Glance Cache .. include:: footer.rst glance-2014.1/doc/source/man/glanceapi.rst0000664000175400017540000000116512323736226021476 0ustar jenkinsjenkins00000000000000========== glance-api ========== --------------------------------------- Server for the Glance Image Service API --------------------------------------- :Author: glance@lists.launchpad.net :Date: 2014-01-16 :Copyright: OpenStack LLC :Version: 2014.1 :Manual section: 1 :Manual group: cloud computing SYNOPSIS ======== glance-api [options] DESCRIPTION =========== glance-api is a server daemon that serves the Glance API OPTIONS ======= **General options** .. include:: general_options.rst FILES ===== **/etc/glance/glance-api.conf** Default configuration file for Glance API .. include:: footer.rst glance-2014.1/doc/source/statuses.rst0000664000175400017540000000557112323736226020660 0ustar jenkinsjenkins00000000000000.. Copyright 2010 OpenStack Foundation All Rights Reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Image Statuses ============== Images in Glance can be in one the following statuses: * ``queued`` The image identifier has been reserved for an image in the Glance registry. No image data has been uploaded to Glance and the image size was not explicitly set to zero on creation. * ``saving`` Denotes that an image's raw data is currently being uploaded to Glance. When an image is registered with a call to `POST /images` and there is an `x-image-meta-location` header present, that image will never be in the `saving` status (as the image data is already available in some other location). * ``active`` Denotes an image that is fully available in Glance. This occurs when the image data is uploaded, or the image size is explicitly set to zero on creation. * ``killed`` Denotes that an error occurred during the uploading of an image's data, and that the image is not readable. * ``deleted`` Glance has retained the information about the image, but it is no longer available to use. An image in this state will be removed automatically at a later date. * ``pending_delete`` This is similar to `deleted`, however, Glance has not yet removed the image data. An image in this state is recoverable. .. figure:: /images/image_status_transition.png :figwidth: 100% :align: center :alt: Image status transition This is a representation of how the image move from one status to the next. * Add location from zero to more than one. * Remove location from one or more to zero by PATCH method which is only supported in v2. Task Statuses ============== Tasks in Glance can be in one the following statuses: * ``pending`` The task identifier has been reserved for a task in the Glance. No processing has begun on it yet. * ``processing`` The task has been picked up by the underlying executor and is being run using the backend Glance execution logic for that task type. * ``success`` Denotes that the task has had a successful run within Glance. The ``result`` field of the task shows more details about the outcome. * ``failure`` Denotes that an error occurred during the execution of the task and it cannot continue processing. The ``message`` field of the task shows what the error was. glance-2014.1/doc/source/authentication.rst0000664000175400017540000001115412323736226022016 0ustar jenkinsjenkins00000000000000.. Copyright 2010 OpenStack Foundation All Rights Reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Authentication With Keystone ============================ Glance may optionally be integrated with Keystone. Setting this up is relatively straightforward, as the Keystone distribution includes the necessary middleware. Once you have installed Keystone and edited your configuration files, newly created images will have their `owner` attribute set to the tenant of the authenticated users, and the `is_public` attribute will cause access to those images for which it is `false` to be restricted to only the owner, users with admin context, or tenants/users with whom the image has been shared. Configuring the Glance servers to use Keystone ---------------------------------------------- Keystone is integrated with Glance through the use of middleware. The default configuration files for both the Glance API and the Glance Registry use a single piece of middleware called ``unauthenticated-context``, which generates a request context containing blank authentication information. In order to configure Glance to use Keystone, the ``authtoken`` and ``context`` middlewares must be deployed in place of the ``unauthenticated-context`` middleware. The ``authtoken`` middleware performs the authentication token validation and retrieves actual user authentication information. It can be found in the Keystone distribution. Configuring Glance API to use Keystone -------------------------------------- Configuring Glance API to use Keystone is relatively straight forward. The first step is to ensure that declarations for the two pieces of middleware exist in the ``glance-api-paste.ini``. Here is an example for ``authtoken``:: [filter:authtoken] paste.filter_factory = keystoneclient.middleware.auth_token:filter_factory auth_host = 127.0.0.1 auth_port = 35357 auth_protocol = http admin_user = glance_admin admin_tenant_name = service_admins admin_password = password1234 The actual values for these variables will need to be set depending on your situation. For more information, please refer to the Keystone documentation on the ``auth_token`` middleware, but in short: * Those variables beginning with ``auth_`` point to the Keystone Admin service. This information is used by the middleware to actually query Keystone about the validity of the authentication tokens. * The admin auth credentials (``admin_user``, ``admin_tenant_name``, ``admin_password``) will be used to retrieve an admin token. That token will be used to authorize user tokens behind the scenes. Finally, to actually enable using Keystone authentication, the application pipeline must be modified. By default, it looks like:: [pipeline:glance-api] pipeline = versionnegotiation unauthenticated-context apiv1app Your particular pipeline may vary depending on other options, such as the image cache. This must be changed by replacing ``unauthenticated-context`` with ``authtoken`` and ``context``:: [pipeline:glance-api] pipeline = versionnegotiation authtoken context apiv1app Configuring Glance Registry to use Keystone ------------------------------------------- Configuring Glance Registry to use Keystone is also relatively straight forward. The same middleware needs to be added to ``glance-registry-paste.ini`` as was needed by Glance API; see above for an example of the ``authtoken`` configuration. Again, to enable using Keystone authentication, the appropriate application pipeline must be selected. By default, it looks like:: [pipeline:glance-registry-keystone] pipeline = authtoken context registryapp To enable the above application pipeline, in your main ``glance-registry.conf`` configuration file, select the appropriate deployment flavor by adding a ``flavor`` attribute in the ``paste_deploy`` group:: [paste_deploy] flavor = keystone .. note:: If your authentication service uses a role other than ``admin`` to identify which users should be granted admin-level privileges, you must define it in the ``admin_role`` config attribute in both ``glance-registry.conf`` and ``glance-api.conf``. glance-2014.1/doc/source/notifications.rst0000664000175400017540000001240512323736226021650 0ustar jenkinsjenkins00000000000000.. Copyright 2011-2013 OpenStack Foundation All Rights Reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Notifications ============= Notifications can be generated for several events in the image lifecycle. These can be used for auditing, troubleshooting, etc. Strategies ---------- * logging This strategy uses the standard Python logging infrastructure with the notifications ending up in file specificed by the log_file configuration directive. * rabbit This strategy sends notifications to a rabbitmq queue. This can then be processed by other services or applications. * qpid This strategy is similar to rabbit. It sends notifications to an AMQP message queue via Qpid. * noop This strategy produces no notifications. It is the default strategy. Notification Types ------------------ * ``image.create`` Emitted when an image record is created in Glance. Image record creation is independent of image data upload. * ``image.prepare`` Emitted when Glance begins uploading image data to its store. * ``image.upload`` Emitted when Glance has completed the upload of image data to its store. * ``image.activate`` Emitted when an image goes to `active` status. This occurs when Glance knows where the image data is located. * ``image.send`` Emitted upon completion of an image being sent to a consumer. * ``image.update`` Emitted when an image record is updated in Glance. * ``image.delete`` Emitted when an image deleted from Glance. * ``task.run`` Emitted when a task is picked up by the executor to be run. * ``task.processing`` Emitted when a task is sent over to the executor to begin processing. * ``task.success`` Emitted when a task is successfully completed. * ``task.failure`` Emitted when a task fails. Content ------- Every message contains a handful of attributes. * message_id UUID identifying the message. * publisher_id The hostname of the glance instance that generated the message. * event_type Event that generated the message. * priority One of WARN, INFO or ERROR. * timestamp UTC timestamp of when event was generated. * payload Data specific to the event type. Payload ------- * image.send The payload for INFO, WARN, and ERROR events contain the following: image_id ID of the image (UUID) owner_id Tenant or User ID that owns this image (string) receiver_tenant_id Tenant ID of the account receiving the image (string) receiver_user_id User ID of the account receiving the image (string) destination_ip bytes_sent The number of bytes actually sent * image.create For INFO events, it is the image metadata. WARN and ERROR events contain a text message in the payload. * image.prepare For INFO events, it is the image metadata. WARN and ERROR events contain a text message in the payload. * image.upload For INFO events, it is the image metadata. WARN and ERROR events contain a text message in the payload. * image.activate For INFO events, it is the image metadata. WARN and ERROR events contain a text message in the payload. * image.update For INFO events, it is the image metadata. WARN and ERROR events contain a text message in the payload. * image.delete For INFO events, it is the image id. WARN and ERROR events contain a text message in the payload. * task.run The payload for INFO, WARN, and ERROR events contain the following: task_id ID of the task (UUID) owner Tenant or User ID that created this task (string) task_type Type of the task. Example, task_type is "import". (string) status, status of the task. Status can be "pending", "processing", "success" or "failure". (string) task_input Input provided by the user when attempting to create a task. (dict) result Resulting output from a successful task. (dict) message Message shown in the task if it fails. None if task succeeds. (string) expires_at UTC time at which the task would not be visible to the user. (string) created_at UTC time at which the task was created. (string) updated_at UTC time at which the task was latest updated. (string) The exceptions are:- For INFO events, it is the task dict with result and message as None. WARN and ERROR events contain a text message in the payload. * task.processing For INFO events, it is the task dict with result and message as None. WARN and ERROR events contain a text message in the payload. * task.success For INFO events, it is the task dict with message as None and result is a dict. WARN and ERROR events contain a text message in the payload. * task.failure For INFO events, it is the task dict with result as None and message is text. WARN and ERROR events contain a text message in the payload. glance-2014.1/doc/source/installing.rst0000664000175400017540000000675612323736226021157 0ustar jenkinsjenkins00000000000000.. Copyright 2011 OpenStack Foundation All Rights Reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Installation ============ Installing from packages ~~~~~~~~~~~~~~~~~~~~~~~~ To install the latest released version of Glance, follow the following instructions. Debian, Ubuntu ############## 1. Add the Glance PPA to your sources.lst:: $> sudo add-apt-repository ppa:glance-core/trunk $> sudo apt-get update 2. Install Glance:: $> sudo apt-get install glance Red Hat, Fedora ############### Only RHEL 6, Fedora 18, and newer releases have the necessary components packaged. On RHEL 6, enable the EPEL repository. Install Glance:: $ su - # yum install openstack-glance Installing from source tarballs ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ To install the latest version of Glance from the Launchpad Bazaar repositories, following the following instructions. 1. Grab the source tarball from `Launchpad `_ 2. Untar the source tarball:: $> tar -xzf 3. Change into the package directory and build/install:: $> cd glance- $> sudo python setup.py install Installing from Git ~~~~~~~~~~~~~~~~~~~ To install the latest version of Glance from the GitHub Git repositories, following the following instructions. Debian, Ubuntu ############## 1. Install Git and build dependencies:: $> sudo apt-get install git $> sudo apt-get build-dep glance .. note:: If you want to build the Glance documentation locally, you will also want to install the python-sphinx package 2. Clone Glance's trunk branch from GitHub:: $> git clone git://github.com/openstack/glance $> cd glance 3. Install Glance:: $> sudo python setup.py install Red Hat, Fedora ############### On Fedora, most developers and essentially all users install packages. Instructions below are not commonly used, and even then typically in a throw-away VM. Since normal build dependencies are resolved by mechanisms of RPM, there is no one-line command to install everything needed by the source repository in git. One common way to discover the dependencies is to search for *BuildRequires:* in the specfile of openstack-glance for the appropriate distro. In case of Fedora 16, for example, do this:: $ su - # yum install git # yum install python2-devel python-setuptools python-distutils-extra # yum install python-webob python-eventlet python-boto # yum install python-virtualenv Build Glance:: $ python setup.py build If any missing modules crop up, install them with yum, then retry the build. .. note:: If you want to build the Glance documentation, you will also want to install the packages python-sphinx and graphviz, then run "python setup.py build_sphinx". Due to required features of python-sphinx 1.0 or better, documentation can only be built on Fedora 15 or later. Test the build:: $ ./run_tests.sh -s Once Glance is built and tested, install it:: $ su - # python setup.py install glance-2014.1/setup.cfg0000664000175400017540000000332112323736427016021 0ustar jenkinsjenkins00000000000000[metadata] name = glance version = 2014.1 summary = OpenStack Image Service description-file = README.rst author = OpenStack author-email = openstack-dev@lists.openstack.org home-page = http://www.openstack.org/ classifier = Environment :: OpenStack Intended Audience :: Information Technology Intended Audience :: System Administrators License :: OSI Approved :: Apache Software License Operating System :: POSIX :: Linux Programming Language :: Python Programming Language :: Python :: 2 Programming Language :: Python :: 2.7 Programming Language :: Python :: 2.6 [global] setup-hooks = pbr.hooks.setup_hook [entry_points] console_scripts = glance-api = glance.cmd.api:main glance-cache-prefetcher = glance.cmd.cache_prefetcher:main glance-cache-pruner = glance.cmd.cache_pruner:main glance-cache-manage = glance.cmd.cache_manage:main glance-cache-cleaner = glance.cmd.cache_cleaner:main glance-control = glance.cmd.control:main glance-manage = glance.cmd.manage:main glance-registry = glance.cmd.registry:main glance-replicator = glance.cmd.replicator:main glance-scrubber = glance.cmd.scrubber:main glance.common.image_location_strategy.modules = location_order_strategy = glance.common.location_strategy.location_order store_type_strategy = glance.common.location_strategy.store_type [build_sphinx] all_files = 1 build-dir = doc/build source-dir = doc/source [egg_info] tag_build = tag_date = 0 tag_svn_revision = 0 [compile_catalog] directory = glance/locale domain = glance [update_catalog] domain = glance output_dir = glance/locale input_file = glance/locale/glance.pot [extract_messages] keywords = _ gettext ngettext l_ lazy_gettext mapping_file = babel.cfg output_file = glance/locale/glance.pot glance-2014.1/setup.py0000664000175400017540000000141512323736226015711 0ustar jenkinsjenkins00000000000000#!/usr/bin/env python # Copyright (c) 2013 Hewlett-Packard Development Company, L.P. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # implied. # See the License for the specific language governing permissions and # limitations under the License. # THIS FILE IS MANAGED BY THE GLOBAL REQUIREMENTS REPO - DO NOT EDIT import setuptools setuptools.setup( setup_requires=['pbr'], pbr=True) glance-2014.1/tools/0000775000175400017540000000000012323736427015341 5ustar jenkinsjenkins00000000000000glance-2014.1/tools/install_venv.py0000664000175400017540000000451712323736226020423 0ustar jenkinsjenkins00000000000000# Copyright 2010 United States Government as represented by the # Administrator of the National Aeronautics and Space Administration. # All Rights Reserved. # # Copyright 2010 OpenStack Foundation # Copyright 2013 IBM Corp. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ Installation script for Glance's development virtualenv """ from __future__ import print_function import os import sys import install_venv_common as install_venv def print_help(): help = """ Glance development environment setup is complete. Glance development uses virtualenv to track and manage Python dependencies while in development and testing. To activate the Glance virtualenv for the extent of your current shell session you can run: $ source .venv/bin/activate Or, if you prefer, you can run commands in the virtualenv on a case by case basis by running: $ tools/with_venv.sh Also, make test will automatically use the virtualenv. """ print(help) def main(argv): root = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) venv = os.path.join(root, '.venv') pip_requires = os.path.join(root, 'requirements.txt') test_requires = os.path.join(root, 'test-requirements.txt') py_version = "python%s.%s" % (sys.version_info[0], sys.version_info[1]) project = 'Glance' install = install_venv.InstallVenv(root, venv, pip_requires, test_requires, py_version, project) options = install.parse_args(argv) install.check_python_version() install.check_dependencies() install.create_virtualenv(no_site_packages=options.no_site_packages) install.install_dependencies() install.run_command([os.path.join(venv, 'bin/python'), 'setup.py', 'develop']) print_help() if __name__ == '__main__': main(sys.argv) glance-2014.1/tools/with_venv.sh0000775000175400017540000000033212323736226017704 0ustar jenkinsjenkins00000000000000#!/bin/bash TOOLS_PATH=${TOOLS_PATH:-$(dirname $0)} VENV_PATH=${VENV_PATH:-${TOOLS_PATH}} VENV_DIR=${VENV_NAME:-/../.venv} TOOLS=${TOOLS_PATH} VENV=${VENV:-${VENV_PATH}/${VENV_DIR}} source ${VENV}/bin/activate && "$@" glance-2014.1/tools/colorizer.py0000775000175400017540000002711612323736226017732 0ustar jenkinsjenkins00000000000000#!/usr/bin/env python # Copyright (c) 2013, Nebula, Inc. # Copyright 2010 United States Government as represented by the # Administrator of the National Aeronautics and Space Administration. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # # Colorizer Code is borrowed from Twisted: # Copyright (c) 2001-2010 Twisted Matrix Laboratories. # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """Display a subunit stream through a colorized unittest test runner.""" import heapq import subunit import sys import unittest import testtools class _AnsiColorizer(object): """ A colorizer is an object that loosely wraps around a stream, allowing callers to write text to the stream in a particular color. Colorizer classes must implement C{supported()} and C{write(text, color)}. """ _colors = dict(black=30, red=31, green=32, yellow=33, blue=34, magenta=35, cyan=36, white=37) def __init__(self, stream): self.stream = stream def supported(cls, stream=sys.stdout): """ A class method that returns True if the current platform supports coloring terminal output using this method. Returns False otherwise. """ if not stream.isatty(): return False # auto color only on TTYs try: import curses except ImportError: return False else: try: try: return curses.tigetnum("colors") > 2 except curses.error: curses.setupterm() return curses.tigetnum("colors") > 2 except Exception: # guess false in case of error return False supported = classmethod(supported) def write(self, text, color): """ Write the given text to the stream in the given color. @param text: Text to be written to the stream. @param color: A string label for a color. e.g. 'red', 'white'. """ color = self._colors[color] self.stream.write('\x1b[%s;1m%s\x1b[0m' % (color, text)) class _Win32Colorizer(object): """ See _AnsiColorizer docstring. """ def __init__(self, stream): import win32console red, green, blue, bold = (win32console.FOREGROUND_RED, win32console.FOREGROUND_GREEN, win32console.FOREGROUND_BLUE, win32console.FOREGROUND_INTENSITY) self.stream = stream self.screenBuffer = win32console.GetStdHandle( win32console.STD_OUT_HANDLE) self._colors = { 'normal': red | green | blue, 'red': red | bold, 'green': green | bold, 'blue': blue | bold, 'yellow': red | green | bold, 'magenta': red | blue | bold, 'cyan': green | blue | bold, 'white': red | green | blue | bold } def supported(cls, stream=sys.stdout): try: import win32console screenBuffer = win32console.GetStdHandle( win32console.STD_OUT_HANDLE) except ImportError: return False import pywintypes try: screenBuffer.SetConsoleTextAttribute( win32console.FOREGROUND_RED | win32console.FOREGROUND_GREEN | win32console.FOREGROUND_BLUE) except pywintypes.error: return False else: return True supported = classmethod(supported) def write(self, text, color): color = self._colors[color] self.screenBuffer.SetConsoleTextAttribute(color) self.stream.write(text) self.screenBuffer.SetConsoleTextAttribute(self._colors['normal']) class _NullColorizer(object): """ See _AnsiColorizer docstring. """ def __init__(self, stream): self.stream = stream def supported(cls, stream=sys.stdout): return True supported = classmethod(supported) def write(self, text, color): self.stream.write(text) def get_elapsed_time_color(elapsed_time): if elapsed_time > 1.0: return 'red' elif elapsed_time > 0.25: return 'yellow' else: return 'green' class SubunitTestResult(testtools.TestResult): def __init__(self, stream, descriptions, verbosity): super(SubunitTestResult, self).__init__() self.stream = stream self.showAll = verbosity > 1 self.num_slow_tests = 10 self.slow_tests = [] # this is a fixed-sized heap self.colorizer = None # NOTE(vish): reset stdout for the terminal check stdout = sys.stdout sys.stdout = sys.__stdout__ for colorizer in [_Win32Colorizer, _AnsiColorizer, _NullColorizer]: if colorizer.supported(): self.colorizer = colorizer(self.stream) break sys.stdout = stdout self.start_time = None self.last_time = {} self.results = {} self.last_written = None def _writeElapsedTime(self, elapsed): color = get_elapsed_time_color(elapsed) self.colorizer.write(" %.2f" % elapsed, color) def _addResult(self, test, *args): try: name = test.id() except AttributeError: name = 'Unknown.unknown' test_class, test_name = name.rsplit('.', 1) elapsed = (self._now() - self.start_time).total_seconds() item = (elapsed, test_class, test_name) if len(self.slow_tests) >= self.num_slow_tests: heapq.heappushpop(self.slow_tests, item) else: heapq.heappush(self.slow_tests, item) self.results.setdefault(test_class, []) self.results[test_class].append((test_name, elapsed) + args) self.last_time[test_class] = self._now() self.writeTests() def _writeResult(self, test_name, elapsed, long_result, color, short_result, success): if self.showAll: self.stream.write(' %s' % str(test_name).ljust(66)) self.colorizer.write(long_result, color) if success: self._writeElapsedTime(elapsed) self.stream.writeln() else: self.colorizer.write(short_result, color) def addSuccess(self, test): super(SubunitTestResult, self).addSuccess(test) self._addResult(test, 'OK', 'green', '.', True) def addFailure(self, test, err): if test.id() == 'process-returncode': return super(SubunitTestResult, self).addFailure(test, err) self._addResult(test, 'FAIL', 'red', 'F', False) def addError(self, test, err): super(SubunitTestResult, self).addFailure(test, err) self._addResult(test, 'ERROR', 'red', 'E', False) def addSkip(self, test, reason=None, details=None): super(SubunitTestResult, self).addSkip(test, reason, details) self._addResult(test, 'SKIP', 'blue', 'S', True) def startTest(self, test): self.start_time = self._now() super(SubunitTestResult, self).startTest(test) def writeTestCase(self, cls): if not self.results.get(cls): return if cls != self.last_written: self.colorizer.write(cls, 'white') self.stream.writeln() for result in self.results[cls]: self._writeResult(*result) del self.results[cls] self.stream.flush() self.last_written = cls def writeTests(self): time = self.last_time.get(self.last_written, self._now()) if not self.last_written or (self._now() - time).total_seconds() > 2.0: diff = 3.0 while diff > 2.0: classes = self.results.keys() oldest = min(classes, key=lambda x: self.last_time[x]) diff = (self._now() - self.last_time[oldest]).total_seconds() self.writeTestCase(oldest) else: self.writeTestCase(self.last_written) def done(self): self.stopTestRun() def stopTestRun(self): for cls in list(self.results.iterkeys()): self.writeTestCase(cls) self.stream.writeln() self.writeSlowTests() def writeSlowTests(self): # Pare out 'fast' tests slow_tests = [item for item in self.slow_tests if get_elapsed_time_color(item[0]) != 'green'] if slow_tests: slow_total_time = sum(item[0] for item in slow_tests) slow = ("Slowest %i tests took %.2f secs:" % (len(slow_tests), slow_total_time)) self.colorizer.write(slow, 'yellow') self.stream.writeln() last_cls = None # sort by name for elapsed, cls, name in sorted(slow_tests, key=lambda x: x[1] + x[2]): if cls != last_cls: self.colorizer.write(cls, 'white') self.stream.writeln() last_cls = cls self.stream.write(' %s' % str(name).ljust(68)) self._writeElapsedTime(elapsed) self.stream.writeln() def printErrors(self): if self.showAll: self.stream.writeln() self.printErrorList('ERROR', self.errors) self.printErrorList('FAIL', self.failures) def printErrorList(self, flavor, errors): for test, err in errors: self.colorizer.write("=" * 70, 'red') self.stream.writeln() self.colorizer.write(flavor, 'red') self.stream.writeln(": %s" % test.id()) self.colorizer.write("-" * 70, 'red') self.stream.writeln() self.stream.writeln("%s" % err) test = subunit.ProtocolTestCase(sys.stdin, passthrough=None) if sys.version_info[0:2] <= (2, 6): runner = unittest.TextTestRunner(verbosity=2) else: runner = unittest.TextTestRunner( verbosity=2, resultclass=SubunitTestResult) if runner.run(test).wasSuccessful(): exit_code = 0 else: exit_code = 1 sys.exit(exit_code) glance-2014.1/tools/install_venv_common.py0000664000175400017540000001350612323736226021771 0ustar jenkinsjenkins00000000000000# Copyright 2013 OpenStack Foundation # Copyright 2013 IBM Corp. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """Provides methods needed by installation script for OpenStack development virtual environments. Since this script is used to bootstrap a virtualenv from the system's Python environment, it should be kept strictly compatible with Python 2.6. Synced in from openstack-common """ from __future__ import print_function import optparse import os import subprocess import sys class InstallVenv(object): def __init__(self, root, venv, requirements, test_requirements, py_version, project): self.root = root self.venv = venv self.requirements = requirements self.test_requirements = test_requirements self.py_version = py_version self.project = project def die(self, message, *args): print(message % args, file=sys.stderr) sys.exit(1) def check_python_version(self): if sys.version_info < (2, 6): self.die("Need Python Version >= 2.6") def run_command_with_code(self, cmd, redirect_output=True, check_exit_code=True): """Runs a command in an out-of-process shell. Returns the output of that command. Working directory is self.root. """ if redirect_output: stdout = subprocess.PIPE else: stdout = None proc = subprocess.Popen(cmd, cwd=self.root, stdout=stdout) output = proc.communicate()[0] if check_exit_code and proc.returncode != 0: self.die('Command "%s" failed.\n%s', ' '.join(cmd), output) return (output, proc.returncode) def run_command(self, cmd, redirect_output=True, check_exit_code=True): return self.run_command_with_code(cmd, redirect_output, check_exit_code)[0] def get_distro(self): if (os.path.exists('/etc/fedora-release') or os.path.exists('/etc/redhat-release')): return Fedora( self.root, self.venv, self.requirements, self.test_requirements, self.py_version, self.project) else: return Distro( self.root, self.venv, self.requirements, self.test_requirements, self.py_version, self.project) def check_dependencies(self): self.get_distro().install_virtualenv() def create_virtualenv(self, no_site_packages=True): """Creates the virtual environment and installs PIP. Creates the virtual environment and installs PIP only into the virtual environment. """ if not os.path.isdir(self.venv): print('Creating venv...', end=' ') if no_site_packages: self.run_command(['virtualenv', '-q', '--no-site-packages', self.venv]) else: self.run_command(['virtualenv', '-q', self.venv]) print('done.') else: print("venv already exists...") pass def pip_install(self, *args): self.run_command(['tools/with_venv.sh', 'pip', 'install', '--upgrade'] + list(args), redirect_output=False) def install_dependencies(self): print('Installing dependencies with pip (this can take a while)...') # First things first, make sure our venv has the latest pip and # setuptools and pbr self.pip_install('pip>=1.4') self.pip_install('setuptools') self.pip_install('pbr') self.pip_install('-r', self.requirements, '-r', self.test_requirements) def parse_args(self, argv): """Parses command-line arguments.""" parser = optparse.OptionParser() parser.add_option('-n', '--no-site-packages', action='store_true', help="Do not inherit packages from global Python " "install") return parser.parse_args(argv[1:])[0] class Distro(InstallVenv): def check_cmd(self, cmd): return bool(self.run_command(['which', cmd], check_exit_code=False).strip()) def install_virtualenv(self): if self.check_cmd('virtualenv'): return if self.check_cmd('easy_install'): print('Installing virtualenv via easy_install...', end=' ') if self.run_command(['easy_install', 'virtualenv']): print('Succeeded') return else: print('Failed') self.die('ERROR: virtualenv not found.\n\n%s development' ' requires virtualenv, please install it using your' ' favorite package management tool' % self.project) class Fedora(Distro): """This covers all Fedora-based distributions. Includes: Fedora, RHEL, CentOS, Scientific Linux """ def check_pkg(self, pkg): return self.run_command_with_code(['rpm', '-q', pkg], check_exit_code=False)[1] == 0 def install_virtualenv(self): if self.check_cmd('virtualenv'): return if not self.check_pkg('python-virtualenv'): self.die("Please install 'python-virtualenv'.") super(Fedora, self).install_virtualenv() glance-2014.1/tools/migrate_image_owners.py0000664000175400017540000000735012323736226022104 0ustar jenkinsjenkins00000000000000#!/usr/bin/python # 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 sys import keystoneclient.v2_0.client from oslo.config import cfg import glance.context import glance.db.sqlalchemy.api as db_api import glance.openstack.common.log as logging import glance.registry.context LOG = logging.getLogger(__name__) LOG.addHandler(logging.StreamHandler()) LOG.setLevel(logging.DEBUG) def get_owner_map(ksclient, owner_is_tenant=True): if owner_is_tenant: entities = ksclient.tenants.list() else: entities = ksclient.users.list() # build mapping of (user or tenant) name to id return dict([(entity.name, entity.id) for entity in entities]) def build_image_owner_map(owner_map, db, context): image_owner_map = {} for image in db.image_get_all(context): image_id = image['id'] owner_name = image['owner'] if not owner_name: LOG.info('Image %s has no owner. Skipping.' % image_id) continue try: owner_id = owner_map[owner_name] except KeyError: msg = 'Image %s owner %s was not found. Skipping.' LOG.error(msg % (image_id, owner_name)) continue image_owner_map[image_id] = owner_id msg = 'Image %s owner %s -> %s' % (image_id, owner_name, owner_id) LOG.info(msg) return image_owner_map def update_image_owners(image_owner_map, db, context): for (image_id, image_owner) in image_owner_map.items(): db.image_update(context, image_id, {'owner': image_owner}) LOG.info('Image %s successfully updated.' % image_id) if __name__ == "__main__": config = cfg.CONF extra_cli_opts = [ cfg.BoolOpt('dry-run', help='Print output but do not make db changes.'), cfg.StrOpt('keystone-auth-uri', help='Authentication endpoint'), cfg.StrOpt('keystone-admin-tenant-name', help='Administrative user\'s tenant name'), cfg.StrOpt('keystone-admin-user', help='Administrative user\'s id'), cfg.StrOpt('keystone-admin-password', help='Administrative user\'s password', secret=True), ] config.register_cli_opts(extra_cli_opts) config(project='glance', prog='glance-registry') db_api.configure_db() context = glance.common.context.RequestContext(is_admin=True) auth_uri = config.keystone_auth_uri admin_tenant_name = config.keystone_admin_tenant_name admin_user = config.keystone_admin_user admin_password = config.keystone_admin_password if not (auth_uri and admin_tenant_name and admin_user and admin_password): LOG.critical('Missing authentication arguments') sys.exit(1) ks = keystoneclient.v2_0.client.Client(username=admin_user, password=admin_password, tenant_name=admin_tenant_name, auth_url=auth_uri) owner_map = get_owner_map(ks, config.owner_is_tenant) image_updates = build_image_owner_map(owner_map, db_api, context) if not config.dry_run: update_image_owners(image_updates, db_api, context) glance-2014.1/README.rst0000664000175400017540000000055012323736226015665 0ustar jenkinsjenkins00000000000000====== Glance ====== Glance is a project that defines services for discovering, registering, retrieving and storing virtual machine images. Use the following resources to learn more: * `Official Glance documentation `_ * `Official Client documentation `_ glance-2014.1/openstack-common.conf0000664000175400017540000000056712323736226020332 0ustar jenkinsjenkins00000000000000[DEFAULT] # The list of modules to copy from openstack-common module=db module=db.sqlalchemy module=fileutils module=gettextutils module=importutils module=install_venv_common module=jsonutils module=local module=lockutils module=log module=policy module=strutils module=test module=timeutils module=units # The base module to hold the copy of openstack.common base=glance glance-2014.1/PKG-INFO0000664000175400017540000000215612323736427015302 0ustar jenkinsjenkins00000000000000Metadata-Version: 1.1 Name: glance Version: 2014.1 Summary: OpenStack Image Service Home-page: http://www.openstack.org/ Author: OpenStack Author-email: openstack-dev@lists.openstack.org License: UNKNOWN Description: ====== Glance ====== Glance is a project that defines services for discovering, registering, retrieving and storing virtual machine images. Use the following resources to learn more: * `Official Glance documentation `_ * `Official Client documentation `_ Platform: UNKNOWN Classifier: Environment :: OpenStack Classifier: Intended Audience :: Information Technology Classifier: Intended Audience :: System Administrators Classifier: License :: OSI Approved :: Apache Software License Classifier: Operating System :: POSIX :: Linux Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 2.6 glance-2014.1/.testr.conf0000664000175400017540000000051612323736226016266 0ustar jenkinsjenkins00000000000000[DEFAULT] test_command=OS_STDOUT_CAPTURE=${OS_STDOUT_CAPTURE:-1} \ OS_STDERR_CAPTURE=${OS_STDERR_CAPTURE:-1} \ OS_TEST_TIMEOUT=${OS_TEST_TIMEOUT:-160} \ ${PYTHON:-python} -m subunit.run discover -t ./ ./glance/tests $LISTOPT $IDOPTION test_id_option=--load-list $IDFILE test_list_option=--list glance-2014.1/etc/0000775000175400017540000000000012323736427014754 5ustar jenkinsjenkins00000000000000glance-2014.1/etc/glance-registry-paste.ini0000664000175400017540000000153712323736226021671 0ustar jenkinsjenkins00000000000000# Use this pipeline for no auth - DEFAULT [pipeline:glance-registry] pipeline = unauthenticated-context registryapp # Use this pipeline for keystone auth [pipeline:glance-registry-keystone] pipeline = authtoken context registryapp # Use this pipeline for authZ only. This means that the registry will treat a # user as authenticated without making requests to keystone to reauthenticate # the user. [pipeline:glance-registry-trusted-auth] pipeline = context registryapp [app:registryapp] paste.app_factory = glance.registry.api:API.factory [filter:context] paste.filter_factory = glance.api.middleware.context:ContextMiddleware.factory [filter:unauthenticated-context] paste.filter_factory = glance.api.middleware.context:UnauthenticatedContextMiddleware.factory [filter:authtoken] paste.filter_factory = keystoneclient.middleware.auth_token:filter_factory glance-2014.1/etc/logging.cnf.sample0000664000175400017540000000172612323736226020355 0ustar jenkinsjenkins00000000000000[loggers] keys=root,api,registry,combined [formatters] keys=normal,normal_with_name,debug [handlers] keys=production,file,devel [logger_root] level=NOTSET handlers=devel [logger_api] level=DEBUG handlers=devel qualname=glance-api [logger_registry] level=DEBUG handlers=devel qualname=glance-registry [logger_combined] level=DEBUG handlers=devel qualname=glance-combined [handler_production] class=handlers.SysLogHandler level=ERROR formatter=normal_with_name args=(('localhost', handlers.SYSLOG_UDP_PORT), handlers.SysLogHandler.LOG_USER) [handler_file] class=FileHandler level=DEBUG formatter=normal_with_name args=('glance.log', 'w') [handler_devel] class=StreamHandler level=NOTSET formatter=debug args=(sys.stdout,) [formatter_normal] format=%(asctime)s %(levelname)s %(message)s [formatter_normal_with_name] format=(%(name)s): %(asctime)s %(levelname)s %(message)s [formatter_debug] format=(%(name)s): %(asctime)s %(levelname)s %(module)s %(funcName)s %(message)s glance-2014.1/etc/glance-registry.conf0000664000175400017540000001354212323736226020724 0ustar jenkinsjenkins00000000000000[DEFAULT] # Show more verbose log output (sets INFO log level output) #verbose = False # Show debugging output in logs (sets DEBUG log level output) #debug = False # Address to bind the registry server bind_host = 0.0.0.0 # Port the bind the registry server to bind_port = 9191 # Log to this file. Make sure you do not set the same log file for both the API # and registry servers! # # If `log_file` is omitted and `use_syslog` is false, then log messages are # sent to stdout as a fallback. log_file = /var/log/glance/registry.log # Backlog requests when creating socket backlog = 4096 # TCP_KEEPIDLE value in seconds when creating socket. # Not supported on OS X. #tcp_keepidle = 600 # API to use for accessing data. Default value points to sqlalchemy # package. #data_api = glance.db.sqlalchemy.api # Enable Registry API versions individually or simultaneously #enable_v1_registry = True #enable_v2_registry = True # Limit the api to return `param_limit_max` items in a call to a container. If # a larger `limit` query param is provided, it will be reduced to this value. api_limit_max = 1000 # If a `limit` query param is not provided in an api request, it will # default to `limit_param_default` limit_param_default = 25 # Role used to identify an authenticated user as administrator #admin_role = admin # Whether to automatically create the database tables. # Default: False #db_auto_create = False # Enable DEBUG log messages from sqlalchemy which prints every database # query and response. # Default: False #sqlalchemy_debug = True # ================= Syslog Options ============================ # Send logs to syslog (/dev/log) instead of to file specified # by `log_file` #use_syslog = False # Facility to use. If unset defaults to LOG_USER. #syslog_log_facility = LOG_LOCAL1 # ================= SSL Options =============================== # Certificate file to use when starting registry server securely #cert_file = /path/to/certfile # Private key file to use when starting registry server securely #key_file = /path/to/keyfile # CA certificate file to use to verify connecting clients #ca_file = /path/to/cafile # ================= Database Options ========================== [database] # The file name to use with SQLite (string value) #sqlite_db = glance.sqlite # If True, SQLite uses synchronous mode (boolean value) #sqlite_synchronous = True # The backend to use for db (string value) # Deprecated group/name - [DEFAULT]/db_backend #backend = sqlalchemy # The SQLAlchemy connection string used to connect to the # database (string value) # Deprecated group/name - [DEFAULT]/sql_connection # Deprecated group/name - [DATABASE]/sql_connection # Deprecated group/name - [sql]/connection #connection = # The SQL mode to be used for MySQL sessions. This option, # including the default, overrides any server-set SQL mode. To # use whatever SQL mode is set by the server configuration, # set this to no value. Example: mysql_sql_mode= (string # value) #mysql_sql_mode = TRADITIONAL # Timeout before idle sql connections are reaped (integer # value) # Deprecated group/name - [DEFAULT]/sql_idle_timeout # Deprecated group/name - [DATABASE]/sql_idle_timeout # Deprecated group/name - [sql]/idle_timeout #idle_timeout = 3600 # Minimum number of SQL connections to keep open in a pool # (integer value) # Deprecated group/name - [DEFAULT]/sql_min_pool_size # Deprecated group/name - [DATABASE]/sql_min_pool_size #min_pool_size = 1 # Maximum number of SQL connections to keep open in a pool # (integer value) # Deprecated group/name - [DEFAULT]/sql_max_pool_size # Deprecated group/name - [DATABASE]/sql_max_pool_size #max_pool_size = # Maximum db connection retries during startup. (setting -1 # implies an infinite retry count) (integer value) # Deprecated group/name - [DEFAULT]/sql_max_retries # Deprecated group/name - [DATABASE]/sql_max_retries #max_retries = 10 # Interval between retries of opening a sql connection # (integer value) # Deprecated group/name - [DEFAULT]/sql_retry_interval # Deprecated group/name - [DATABASE]/reconnect_interval #retry_interval = 10 # If set, use this value for max_overflow with sqlalchemy # (integer value) # Deprecated group/name - [DEFAULT]/sql_max_overflow # Deprecated group/name - [DATABASE]/sqlalchemy_max_overflow #max_overflow = # Verbosity of SQL debugging information. 0=None, # 100=Everything (integer value) # Deprecated group/name - [DEFAULT]/sql_connection_debug #connection_debug = 0 # Add python stack traces to SQL as comment strings (boolean # value) # Deprecated group/name - [DEFAULT]/sql_connection_trace #connection_trace = False # If set, use this value for pool_timeout with sqlalchemy # (integer value) # Deprecated group/name - [DATABASE]/sqlalchemy_pool_timeout #pool_timeout = # Enable the experimental use of database reconnect on # connection lost (boolean value) #use_db_reconnect = False # seconds between db connection retries (integer value) #db_retry_interval = 1 # Whether to increase interval between db connection retries, # up to db_max_retry_interval (boolean value) #db_inc_retry_interval = True # max seconds between db connection retries, if # db_inc_retry_interval is enabled (integer value) #db_max_retry_interval = 10 # maximum db connection retries before error is raised. # (setting -1 implies an infinite retry count) (integer value) #db_max_retries = 20 [keystone_authtoken] auth_host = 127.0.0.1 auth_port = 35357 auth_protocol = http admin_tenant_name = %SERVICE_TENANT_NAME% admin_user = %SERVICE_USER% admin_password = %SERVICE_PASSWORD% [paste_deploy] # Name of the paste configuration file that defines the available pipelines #config_file = glance-registry-paste.ini # Partial name of a pipeline in your paste configuration file with the # service name removed. For example, if your paste section name is # [pipeline:glance-registry-keystone], you would configure the flavor below # as 'keystone'. #flavor= glance-2014.1/etc/glance-cache.conf0000664000175400017540000001605212323736226020116 0ustar jenkinsjenkins00000000000000[DEFAULT] # Show more verbose log output (sets INFO log level output) #verbose = False # Show debugging output in logs (sets DEBUG log level output) #debug = False # Log to this file. Make sure you do not set the same log file for both the API # and registry servers! # # If `log_file` is omitted and `use_syslog` is false, then log messages are # sent to stdout as a fallback. log_file = /var/log/glance/image-cache.log # Send logs to syslog (/dev/log) instead of to file specified by `log_file` #use_syslog = False # Directory that the Image Cache writes data to image_cache_dir = /var/lib/glance/image-cache/ # Number of seconds after which we should consider an incomplete image to be # stalled and eligible for reaping image_cache_stall_time = 86400 # Max cache size in bytes image_cache_max_size = 10737418240 # Address to find the registry server registry_host = 0.0.0.0 # Port the registry server is listening on registry_port = 9191 # 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% # List of which store classes and store class locations are # currently known to glance at startup. # known_stores = glance.store.filesystem.Store, # glance.store.http.Store, # glance.store.rbd.Store, # glance.store.s3.Store, # glance.store.swift.Store, # glance.store.sheepdog.Store, # glance.store.cinder.Store, # glance.store.vmware_datastore.Store, # ============ Filesystem Store Options ======================== # Directory that the Filesystem backend store # writes image data to filesystem_store_datadir = /var/lib/glance/images/ # ============ Swift Store Options ============================= # Version of the authentication service to use # Valid versions are '2' for keystone and '1' for swauth and rackspace swift_store_auth_version = 2 # Address where the Swift authentication service lives # Valid schemes are 'http://' and 'https://' # If no scheme specified, default to 'https://' # For swauth, use something like '127.0.0.1:8080/v1.0/' swift_store_auth_address = 127.0.0.1:5000/v2.0/ # User to authenticate against the Swift authentication service # If you use Swift authentication service, set it to 'account':'user' # where 'account' is a Swift storage account and 'user' # is a user in that account swift_store_user = jdoe:jdoe # Auth key for the user authenticating against the # Swift authentication service swift_store_key = a86850deb2742ec3cb41518e26aa2d89 # Container within the account that the account should use # for storing images in Swift swift_store_container = glance # Do we create the container if it does not exist? swift_store_create_container_on_put = False # What size, in MB, should Glance start chunking image files # and do a large object manifest in Swift? By default, this is # the maximum object size in Swift, which is 5GB swift_store_large_object_size = 5120 # When doing a large object manifest, what size, in MB, should # Glance write chunks to Swift? This amount of data is written # to a temporary disk buffer during the process of chunking # the image file, and the default is 200MB swift_store_large_object_chunk_size = 200 # Whether to use ServiceNET to communicate with the Swift storage servers. # (If you aren't RACKSPACE, leave this False!) # # To use ServiceNET for authentication, prefix hostname of # `swift_store_auth_address` with 'snet-'. # Ex. https://example.com/v1.0/ -> https://snet-example.com/v1.0/ swift_enable_snet = False # ============ S3 Store Options ============================= # Address where the S3 authentication service lives # Valid schemes are 'http://' and 'https://' # If no scheme specified, default to 'http://' s3_store_host = 127.0.0.1:8080/v1.0/ # User to authenticate against the S3 authentication service s3_store_access_key = <20-char AWS access key> # Auth key for the user authenticating against the # S3 authentication service s3_store_secret_key = <40-char AWS secret key> # Container within the account that the account should use # for storing images in S3. Note that S3 has a flat namespace, # so you need a unique bucket name for your glance images. An # easy way to do this is append your AWS access key to "glance". # S3 buckets in AWS *must* be lowercased, so remember to lowercase # your AWS access key if you use it in your bucket name below! s3_store_bucket = glance # Do we create the bucket if it does not exist? s3_store_create_bucket_on_put = False # When sending images to S3, the data will first be written to a # temporary buffer on disk. By default the platform's temporary directory # will be used. If required, an alternative directory can be specified here. # s3_store_object_buffer_dir = /path/to/dir # ============ Cinder Store Options =========================== # Info to match when looking for cinder in the service catalog # Format is : separated values of the form: # :: (string value) #cinder_catalog_info = volume:cinder:publicURL # Override service catalog lookup with template for cinder endpoint # e.g. http://localhost:8776/v1/%(project_id)s (string value) #cinder_endpoint_template = # Region name of this node (string value) #os_region_name = # Location of ca certicates file to use for cinder client requests # (string value) #cinder_ca_certificates_file = # Number of cinderclient retries on failed http calls (integer value) #cinder_http_retries = 3 # Allow to perform insecure SSL requests to cinder (boolean value) #cinder_api_insecure = False # ============ VMware Datastore Store Options ===================== # ESX/ESXi or vCenter Server target system. # The server value can be an IP address or a DNS name # e.g. 127.0.0.1, 127.0.0.1:443, www.vmware-infra.com #vmware_server_host = # Server username (string value) #vmware_server_username = # Server password (string value) #vmware_server_password = # Inventory path to a datacenter (string value) # Value optional when vmware_server_ip is an ESX/ESXi host: if specified # should be `ha-datacenter`. #vmware_datacenter_path = # Datastore associated with the datacenter (string value) #vmware_datastore_name = # The number of times we retry on failures # e.g., socket error, etc (integer value) #vmware_api_retry_count = 10 # The interval used for polling remote tasks # invoked on VMware ESX/VC server in seconds (integer value) #vmware_task_poll_interval = 5 # Absolute path of the folder containing the images in the datastore # (string value) #vmware_store_image_dir = /openstack_glance # Allow to perform insecure SSL requests to the target system (boolean value) #vmware_api_insecure = False # ================= Security Options ========================== # AES key for encrypting store 'location' metadata, including # -- if used -- Swift or S3 credentials # Should be set to a random string of length 16, 24 or 32 bytes # metadata_encryption_key = <16, 24 or 32 char registry metadata key> glance-2014.1/etc/property-protections-policies.conf.sample0000664000175400017540000000224212323736226025140 0ustar jenkinsjenkins00000000000000# property-protections-policies.conf.sample # # This file is an example config file for when # property_protection_rule_format=policies is enabled. # # Specify regular expression for which properties will be protected in [] # For each section, specify CRUD permissions. You may refer to policies defined # in policy.json. # The property rules will be applied in the order specified. Once # a match is found the remaining property rules will not be applied. # # WARNING: # * If the reg ex specified below does not compile, then # the glance-api service fails to start. (Guide for reg ex python compiler # used: # http://docs.python.org/2/library/re.html#regular-expression-syntax) # * If an operation(create, read, update, delete) is not specified or misspelt # then the glance-api service fails to start. # So, remember, with GREAT POWER comes GREAT RESPONSIBILITY! # # NOTE: Only one policy can be specified per action. If multiple policies are # specified, then the glance-api service fails to start. [^x_.*] create = default read = default update = default delete = default [.*] create = context_is_admin read = context_is_admin update = context_is_admin delete = context_is_admin glance-2014.1/etc/glance-api-paste.ini0000664000175400017540000000505312323736226020567 0ustar jenkinsjenkins00000000000000# Use this pipeline for no auth or image caching - DEFAULT [pipeline:glance-api] pipeline = versionnegotiation unauthenticated-context rootapp # Use this pipeline for image caching and no auth [pipeline:glance-api-caching] pipeline = versionnegotiation unauthenticated-context cache rootapp # Use this pipeline for caching w/ management interface but no auth [pipeline:glance-api-cachemanagement] pipeline = versionnegotiation unauthenticated-context cache cachemanage rootapp # Use this pipeline for keystone auth [pipeline:glance-api-keystone] pipeline = versionnegotiation authtoken context rootapp # Use this pipeline for keystone auth with image caching [pipeline:glance-api-keystone+caching] pipeline = versionnegotiation authtoken context cache rootapp # Use this pipeline for keystone auth with caching and cache management [pipeline:glance-api-keystone+cachemanagement] pipeline = versionnegotiation authtoken context cache cachemanage rootapp # Use this pipeline for authZ only. This means that the registry will treat a # user as authenticated without making requests to keystone to reauthenticate # the user. [pipeline:glance-api-trusted-auth] pipeline = versionnegotiation context rootapp # Use this pipeline for authZ only. This means that the registry will treat a # user as authenticated without making requests to keystone to reauthenticate # the user and uses cache management [pipeline:glance-api-trusted-auth+cachemanagement] pipeline = versionnegotiation context cache cachemanage rootapp [composite:rootapp] paste.composite_factory = glance.api:root_app_factory /: apiversions /v1: apiv1app /v2: apiv2app [app:apiversions] paste.app_factory = glance.api.versions:create_resource [app:apiv1app] paste.app_factory = glance.api.v1.router:API.factory [app:apiv2app] paste.app_factory = glance.api.v2.router:API.factory [filter:versionnegotiation] paste.filter_factory = glance.api.middleware.version_negotiation:VersionNegotiationFilter.factory [filter:cache] paste.filter_factory = glance.api.middleware.cache:CacheFilter.factory [filter:cachemanage] paste.filter_factory = glance.api.middleware.cache_manage:CacheManageFilter.factory [filter:context] paste.filter_factory = glance.api.middleware.context:ContextMiddleware.factory [filter:unauthenticated-context] paste.filter_factory = glance.api.middleware.context:UnauthenticatedContextMiddleware.factory [filter:authtoken] paste.filter_factory = keystoneclient.middleware.auth_token:filter_factory delay_auth_decision = true [filter:gzip] paste.filter_factory = glance.api.middleware.gzip:GzipMiddleware.factory glance-2014.1/etc/glance-scrubber.conf0000664000175400017540000000350412323736226020660 0ustar jenkinsjenkins00000000000000[DEFAULT] # Show more verbose log output (sets INFO log level output) #verbose = False # Show debugging output in logs (sets DEBUG log level output) #debug = False # Log to this file. Make sure you do not set the same log file for both the API # and registry servers! # # If `log_file` is omitted and `use_syslog` is false, then log messages are # sent to stdout as a fallback. log_file = /var/log/glance/scrubber.log # Send logs to syslog (/dev/log) instead of to file specified by `log_file` #use_syslog = False # Should we run our own loop or rely on cron/scheduler to run us daemon = False # Loop time between checking for new items to schedule for delete wakeup_time = 300 # Directory that the scrubber will use to remind itself of what to delete # Make sure this is also set in glance-api.conf scrubber_datadir = /var/lib/glance/scrubber # Only one server in your deployment should be designated the cleanup host cleanup_scrubber = False # pending_delete items older than this time are candidates for cleanup cleanup_scrubber_time = 86400 # Address to find the registry server for cleanups registry_host = 0.0.0.0 # Port the registry server is listening on registry_port = 9191 # 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% # Directory to use for lock files. Default to a temp directory # (string value). This setting needs to be the same for both # glance-scrubber and glance-api. #lock_path= # ================= Security Options ========================== # AES key for encrypting store 'location' metadata, including # -- if used -- Swift or S3 credentials # Should be set to a random string of length 16, 24 or 32 bytes #metadata_encryption_key = <16, 24 or 32 char registry metadata key> glance-2014.1/etc/glance-api.conf0000664000175400017540000005667412323736226017642 0ustar jenkinsjenkins00000000000000[DEFAULT] # Show more verbose log output (sets INFO log level output) #verbose = False # Show debugging output in logs (sets DEBUG log level output) #debug = False # Which backend scheme should Glance use by default is not specified # in a request to add a new image to Glance? Known schemes are determined # by the known_stores option below. # Default: 'file' default_store = file # List of which store classes and store class locations are # currently known to glance at startup. # Existing but disabled stores: # glance.store.rbd.Store, # glance.store.s3.Store, # glance.store.swift.Store, # glance.store.sheepdog.Store, # glance.store.cinder.Store, # glance.store.gridfs.Store, # glance.store.vmware_datastore.Store, #known_stores = glance.store.filesystem.Store, # glance.store.http.Store # Maximum image size (in bytes) that may be uploaded through the # Glance API server. Defaults to 1 TB. # WARNING: this value should only be increased after careful consideration # and must be set to a value under 8 EB (9223372036854775808). #image_size_cap = 1099511627776 # Address to bind the API server bind_host = 0.0.0.0 # Port the bind the API server to bind_port = 9292 # Log to this file. Make sure you do not set the same log file for both the API # and registry servers! # # If `log_file` is omitted and `use_syslog` is false, then log messages are # sent to stdout as a fallback. log_file = /var/log/glance/api.log # Backlog requests when creating socket backlog = 4096 # TCP_KEEPIDLE value in seconds when creating socket. # Not supported on OS X. #tcp_keepidle = 600 # API to use for accessing data. Default value points to sqlalchemy # package, it is also possible to use: glance.db.registry.api # data_api = glance.db.sqlalchemy.api # Number of Glance API worker processes to start. # On machines with more than one CPU increasing this value # may improve performance (especially if using SSL with # compression turned on). It is typically recommended to set # this value to the number of CPUs present on your machine. workers = 1 # Maximum line size of message headers to be accepted. # max_header_line may need to be increased when using large tokens # (typically those generated by the Keystone v3 API with big service # catalogs) # max_header_line = 16384 # Role used to identify an authenticated user as administrator #admin_role = admin # Allow unauthenticated users to access the API with read-only # privileges. This only applies when using ContextMiddleware. #allow_anonymous_access = False # Allow access to version 1 of glance api #enable_v1_api = True # Allow access to version 2 of glance api #enable_v2_api = True # Return the URL that references where the data is stored on # the backend storage system. For example, if using the # file system store a URL of 'file:///path/to/image' will # be returned to the user in the 'direct_url' meta-data field. # The default value is false. #show_image_direct_url = False # Send headers containing user and tenant information when making requests to # the v1 glance registry. This allows the registry to function as if a user is # authenticated without the need to authenticate a user itself using the # auth_token middleware. # The default value is false. #send_identity_headers = False # Supported values for the 'container_format' image attribute #container_formats=ami,ari,aki,bare,ovf,ova # Supported values for the 'disk_format' image attribute #disk_formats=ami,ari,aki,vhd,vmdk,raw,qcow2,vdi,iso # Directory to use for lock files. Default to a temp directory # (string value). This setting needs to be the same for both # glance-scrubber and glance-api. #lock_path= # Property Protections config file # This file contains the rules for property protections and the roles/policies # associated with it. # If this config value is not specified, by default, property protections # won't be enforced. # If a value is specified and the file is not found, then the glance-api # service will not start. #property_protection_file = # Specify whether 'roles' or 'policies' are used in the # property_protection_file. # The default value for property_protection_rule_format is 'roles'. #property_protection_rule_format = roles # Specifies how long (in hours) a task is supposed to live in the tasks DB # after succeeding or failing before getting soft-deleted. # The default value for task_time_to_live is 48 hours. # task_time_to_live = 48 # This value sets what strategy will be used to determine the image location # order. Currently two strategies are packaged with Glance 'location_order' # and 'store_type'. #location_strategy = location_order # ================= Syslog Options ============================ # Send logs to syslog (/dev/log) instead of to file specified # by `log_file` #use_syslog = False # Facility to use. If unset defaults to LOG_USER. #syslog_log_facility = LOG_LOCAL0 # ================= SSL Options =============================== # Certificate file to use when starting API server securely #cert_file = /path/to/certfile # Private key file to use when starting API server securely #key_file = /path/to/keyfile # CA certificate file to use to verify connecting clients #ca_file = /path/to/cafile # ================= Security Options ========================== # AES key for encrypting store 'location' metadata, including # -- if used -- Swift or S3 credentials # Should be set to a random string of length 16, 24 or 32 bytes #metadata_encryption_key = <16, 24 or 32 char registry metadata key> # ============ Registry Options =============================== # Address to find the registry server registry_host = 0.0.0.0 # Port the registry server is listening on registry_port = 9191 # What protocol to use when connecting to the registry server? # Set to https for secure HTTP communication registry_client_protocol = http # The path to the key file to use in SSL connections to the # registry server, if any. Alternately, you may set the # GLANCE_CLIENT_KEY_FILE environ variable to a filepath of the key file #registry_client_key_file = /path/to/key/file # The path to the cert file to use in SSL connections to the # registry server, if any. Alternately, you may set the # GLANCE_CLIENT_CERT_FILE environ variable to a filepath of the cert file #registry_client_cert_file = /path/to/cert/file # The path to the certifying authority cert file to use in SSL connections # to the registry server, if any. Alternately, you may set the # GLANCE_CLIENT_CA_FILE environ variable to a filepath of the CA cert file #registry_client_ca_file = /path/to/ca/file # When using SSL in connections to the registry server, do not require # validation via a certifying authority. This is the registry's equivalent of # specifying --insecure on the command line using glanceclient for the API # Default: False #registry_client_insecure = False # The period of time, in seconds, that the API server will wait for a registry # request to complete. A value of '0' implies no timeout. # Default: 600 #registry_client_timeout = 600 # Whether to automatically create the database tables. # Default: False #db_auto_create = False # Enable DEBUG log messages from sqlalchemy which prints every database # query and response. # Default: False #sqlalchemy_debug = True # Pass the user's token through for API requests to the registry. # Default: True #use_user_token = True # If 'use_user_token' is not in effect then admin credentials # can be specified. Requests to the registry on behalf of # the API will use these credentials. # Admin user name #admin_user = None # Admin password #admin_password = None # Admin tenant name #admin_tenant_name = None # Keystone endpoint #auth_url = None # Keystone region #auth_region = None # Auth strategy #auth_strategy = keystone # ============ Notification System Options ===================== # Notifications can be sent when images are create, updated or deleted. # There are three methods of sending notifications, logging (via the # log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid # message queue), or noop (no notifications sent, the default) # NOTE: THIS CONFIGURATION OPTION HAS BEEN DEPRECATED IN FAVOR OF `notification_driver` # notifier_strategy = default # Driver or drivers to handle sending notifications # notification_driver = noop # Default publisher_id for outgoing notifications. # default_publisher_id = image.localhost # Configuration options if sending notifications via rabbitmq (these are # the defaults) rabbit_host = localhost rabbit_port = 5672 rabbit_use_ssl = false rabbit_userid = guest rabbit_password = guest rabbit_virtual_host = / rabbit_notification_exchange = glance rabbit_notification_topic = notifications rabbit_durable_queues = False # Configuration options if sending notifications via Qpid (these are # the defaults) qpid_notification_exchange = glance qpid_notification_topic = notifications qpid_hostname = localhost qpid_port = 5672 qpid_username = qpid_password = qpid_sasl_mechanisms = qpid_reconnect_timeout = 0 qpid_reconnect_limit = 0 qpid_reconnect_interval_min = 0 qpid_reconnect_interval_max = 0 qpid_reconnect_interval = 0 qpid_heartbeat = 5 # Set to 'ssl' to enable SSL qpid_protocol = tcp qpid_tcp_nodelay = True # ============ Filesystem Store Options ======================== # Directory that the Filesystem backend store # writes image data to filesystem_store_datadir = /var/lib/glance/images/ # A list of directories where image data can be stored. # This option may be specified multiple times for specifying multiple store # directories. Either one of filesystem_store_datadirs or # filesystem_store_datadir option is required. A priority number may be given # after each directory entry, separated by a ":". # When adding an image, the highest priority directory will be selected, unless # there is not enough space available in cases where the image size is already # known. If no priority is given, it is assumed to be zero and the directory # will be considered for selection last. If multiple directories have the same # priority, then the one with the most free space available is selected. # If same store is specified multiple times then BadStoreConfiguration # exception will be raised. #filesystem_store_datadirs = /var/lib/glance/images/:1 # A path to a JSON file that contains metadata describing the storage # system. When show_multiple_locations is True the information in this # file will be returned with any location that is contained in this # store. #filesystem_store_metadata_file = None # ============ Swift Store Options ============================= # Version of the authentication service to use # Valid versions are '2' for keystone and '1' for swauth and rackspace swift_store_auth_version = 2 # Address where the Swift authentication service lives # Valid schemes are 'http://' and 'https://' # If no scheme specified, default to 'https://' # For swauth, use something like '127.0.0.1:8080/v1.0/' swift_store_auth_address = 127.0.0.1:5000/v2.0/ # User to authenticate against the Swift authentication service # If you use Swift authentication service, set it to 'account':'user' # where 'account' is a Swift storage account and 'user' # is a user in that account swift_store_user = jdoe:jdoe # Auth key for the user authenticating against the # Swift authentication service swift_store_key = a86850deb2742ec3cb41518e26aa2d89 # Container within the account that the account should use # for storing images in Swift swift_store_container = glance # Do we create the container if it does not exist? swift_store_create_container_on_put = False # What size, in MB, should Glance start chunking image files # and do a large object manifest in Swift? By default, this is # the maximum object size in Swift, which is 5GB swift_store_large_object_size = 5120 # When doing a large object manifest, what size, in MB, should # Glance write chunks to Swift? This amount of data is written # to a temporary disk buffer during the process of chunking # the image file, and the default is 200MB swift_store_large_object_chunk_size = 200 # Whether to use ServiceNET to communicate with the Swift storage servers. # (If you aren't RACKSPACE, leave this False!) # # To use ServiceNET for authentication, prefix hostname of # `swift_store_auth_address` with 'snet-'. # Ex. https://example.com/v1.0/ -> https://snet-example.com/v1.0/ swift_enable_snet = False # If set to True enables multi-tenant storage mode which causes Glance images # to be stored in tenant specific Swift accounts. #swift_store_multi_tenant = False # A list of swift ACL strings that will be applied as both read and # write ACLs to the containers created by Glance in multi-tenant # mode. This grants the specified tenants/users read and write access # to all newly created image objects. The standard swift ACL string # formats are allowed, including: # : # : # *: # Multiple ACLs can be combined using a comma separated list, for # example: swift_store_admin_tenants = service:glance,*:admin #swift_store_admin_tenants = # The region of the swift endpoint to be used for single tenant. This setting # is only necessary if the tenant has multiple swift endpoints. #swift_store_region = # If set to False, disables SSL layer compression of https swift requests. # Setting to 'False' may improve performance for images which are already # in a compressed format, eg qcow2. If set to True, enables SSL layer # compression (provided it is supported by the target swift proxy). #swift_store_ssl_compression = True # The number of times a Swift download will be retried before the # request fails #swift_store_retry_get_count = 0 # ============ S3 Store Options ============================= # Address where the S3 authentication service lives # Valid schemes are 'http://' and 'https://' # If no scheme specified, default to 'http://' s3_store_host = 127.0.0.1:8080/v1.0/ # User to authenticate against the S3 authentication service s3_store_access_key = <20-char AWS access key> # Auth key for the user authenticating against the # S3 authentication service s3_store_secret_key = <40-char AWS secret key> # Container within the account that the account should use # for storing images in S3. Note that S3 has a flat namespace, # so you need a unique bucket name for your glance images. An # easy way to do this is append your AWS access key to "glance". # S3 buckets in AWS *must* be lowercased, so remember to lowercase # your AWS access key if you use it in your bucket name below! s3_store_bucket = glance # Do we create the bucket if it does not exist? s3_store_create_bucket_on_put = False # When sending images to S3, the data will first be written to a # temporary buffer on disk. By default the platform's temporary directory # will be used. If required, an alternative directory can be specified here. #s3_store_object_buffer_dir = /path/to/dir # When forming a bucket url, boto will either set the bucket name as the # subdomain or as the first token of the path. Amazon's S3 service will # accept it as the subdomain, but Swift's S3 middleware requires it be # in the path. Set this to 'path' or 'subdomain' - defaults to 'subdomain'. #s3_store_bucket_url_format = subdomain # ============ RBD Store Options ============================= # Ceph configuration file path # If using cephx authentication, this file should # include a reference to the right keyring # in a client. section #rbd_store_ceph_conf = /etc/ceph/ceph.conf # RADOS user to authenticate as (only applicable if using cephx) # If , a default will be chosen based on the client. section # in rbd_store_ceph_conf #rbd_store_user = # RADOS pool in which images are stored #rbd_store_pool = images # RADOS images will be chunked into objects of this size (in megabytes). # For best performance, this should be a power of two #rbd_store_chunk_size = 8 # ============ Sheepdog Store Options ============================= sheepdog_store_address = localhost sheepdog_store_port = 7000 # Images will be chunked into objects of this size (in megabytes). # For best performance, this should be a power of two sheepdog_store_chunk_size = 64 # ============ Cinder Store Options =============================== # Info to match when looking for cinder in the service catalog # Format is : separated values of the form: # :: (string value) #cinder_catalog_info = volume:cinder:publicURL # Override service catalog lookup with template for cinder endpoint # e.g. http://localhost:8776/v1/%(project_id)s (string value) #cinder_endpoint_template = # Region name of this node (string value) #os_region_name = # Location of ca certicates file to use for cinder client requests # (string value) #cinder_ca_certificates_file = # Number of cinderclient retries on failed http calls (integer value) #cinder_http_retries = 3 # Allow to perform insecure SSL requests to cinder (boolean value) #cinder_api_insecure = False # ============ VMware Datastore Store Options ===================== # ESX/ESXi or vCenter Server target system. # The server value can be an IP address or a DNS name # e.g. 127.0.0.1, 127.0.0.1:443, www.vmware-infra.com #vmware_server_host = # Server username (string value) #vmware_server_username = # Server password (string value) #vmware_server_password = # Inventory path to a datacenter (string value) # Value optional when vmware_server_ip is an ESX/ESXi host: if specified # should be `ha-datacenter`. #vmware_datacenter_path = # Datastore associated with the datacenter (string value) #vmware_datastore_name = # The number of times we retry on failures # e.g., socket error, etc (integer value) #vmware_api_retry_count = 10 # The interval used for polling remote tasks # invoked on VMware ESX/VC server in seconds (integer value) #vmware_task_poll_interval = 5 # Absolute path of the folder containing the images in the datastore # (string value) #vmware_store_image_dir = /openstack_glance # Allow to perform insecure SSL requests to the target system (boolean value) #vmware_api_insecure = False # ============ Delayed Delete Options ============================= # Turn on/off delayed delete delayed_delete = False # Delayed delete time in seconds scrub_time = 43200 # Directory that the scrubber will use to remind itself of what to delete # Make sure this is also set in glance-scrubber.conf scrubber_datadir = /var/lib/glance/scrubber # =============== Quota Options ================================== # The maximum number of image members allowed per image #image_member_quota = 128 # The maximum number of image properties allowed per image #image_property_quota = 128 # The maximum number of tags allowed per image #image_tag_quota = 128 # The maximum number of locations allowed per image #image_location_quota = 10 # Set a system wide quota for every user. This value is the total number # of bytes that a user can use across all storage systems. A value of # 0 means unlimited. #user_storage_quota = 0 # =============== Image Cache Options ============================= # Base directory that the Image Cache uses image_cache_dir = /var/lib/glance/image-cache/ # =============== Manager Options ================================= # DEPRECATED. TO BE REMOVED IN THE JUNO RELEASE. # Whether or not to enforce that all DB tables have charset utf8. # If your database tables do not have charset utf8 you will # need to convert before this option is removed. This option is # only relevant if your database engine is MySQL. #db_enforce_mysql_charset = True # =============== Database Options ================================= [database] # The file name to use with SQLite (string value) #sqlite_db = glance.sqlite # If True, SQLite uses synchronous mode (boolean value) #sqlite_synchronous = True # The backend to use for db (string value) # Deprecated group/name - [DEFAULT]/db_backend #backend = sqlalchemy # The SQLAlchemy connection string used to connect to the # database (string value) # Deprecated group/name - [DEFAULT]/sql_connection # Deprecated group/name - [DATABASE]/sql_connection # Deprecated group/name - [sql]/connection #connection = # The SQL mode to be used for MySQL sessions. This option, # including the default, overrides any server-set SQL mode. To # use whatever SQL mode is set by the server configuration, # set this to no value. Example: mysql_sql_mode= (string # value) #mysql_sql_mode = TRADITIONAL # Timeout before idle sql connections are reaped (integer # value) # Deprecated group/name - [DEFAULT]/sql_idle_timeout # Deprecated group/name - [DATABASE]/sql_idle_timeout # Deprecated group/name - [sql]/idle_timeout #idle_timeout = 3600 # Minimum number of SQL connections to keep open in a pool # (integer value) # Deprecated group/name - [DEFAULT]/sql_min_pool_size # Deprecated group/name - [DATABASE]/sql_min_pool_size #min_pool_size = 1 # Maximum number of SQL connections to keep open in a pool # (integer value) # Deprecated group/name - [DEFAULT]/sql_max_pool_size # Deprecated group/name - [DATABASE]/sql_max_pool_size #max_pool_size = # Maximum db connection retries during startup. (setting -1 # implies an infinite retry count) (integer value) # Deprecated group/name - [DEFAULT]/sql_max_retries # Deprecated group/name - [DATABASE]/sql_max_retries #max_retries = 10 # Interval between retries of opening a sql connection # (integer value) # Deprecated group/name - [DEFAULT]/sql_retry_interval # Deprecated group/name - [DATABASE]/reconnect_interval #retry_interval = 10 # If set, use this value for max_overflow with sqlalchemy # (integer value) # Deprecated group/name - [DEFAULT]/sql_max_overflow # Deprecated group/name - [DATABASE]/sqlalchemy_max_overflow #max_overflow = # Verbosity of SQL debugging information. 0=None, # 100=Everything (integer value) # Deprecated group/name - [DEFAULT]/sql_connection_debug #connection_debug = 0 # Add python stack traces to SQL as comment strings (boolean # value) # Deprecated group/name - [DEFAULT]/sql_connection_trace #connection_trace = False # If set, use this value for pool_timeout with sqlalchemy # (integer value) # Deprecated group/name - [DATABASE]/sqlalchemy_pool_timeout #pool_timeout = # Enable the experimental use of database reconnect on # connection lost (boolean value) #use_db_reconnect = False # seconds between db connection retries (integer value) #db_retry_interval = 1 # Whether to increase interval between db connection retries, # up to db_max_retry_interval (boolean value) #db_inc_retry_interval = True # max seconds between db connection retries, if # db_inc_retry_interval is enabled (integer value) #db_max_retry_interval = 10 # maximum db connection retries before error is raised. # (setting -1 implies an infinite retry count) (integer value) #db_max_retries = 20 [keystone_authtoken] auth_host = 127.0.0.1 auth_port = 35357 auth_protocol = http admin_tenant_name = %SERVICE_TENANT_NAME% admin_user = %SERVICE_USER% admin_password = %SERVICE_PASSWORD% [paste_deploy] # Name of the paste configuration file that defines the available pipelines #config_file = glance-api-paste.ini # Partial name of a pipeline in your paste configuration file with the # service name removed. For example, if your paste section name is # [pipeline:glance-api-keystone], you would configure the flavor below # as 'keystone'. #flavor= [store_type_location_strategy] # The scheme list to use to get store preference order. The scheme must be # registered by one of the stores defined by the 'known_stores' config option. # This option will be applied when you using 'store_type' option as image # location strategy defined by the 'location_strategy' config option. #store_type_preference = glance-2014.1/etc/property-protections-roles.conf.sample0000664000175400017540000000205112323736226024453 0ustar jenkinsjenkins00000000000000# property-protections-roles.conf.sample # # This file is an example config file for when # property_protection_rule_format=roles is enabled. # # Specify regular expression for which properties will be protected in [] # For each section, specify CRUD permissions. # The property rules will be applied in the order specified. Once # a match is found the remaining property rules will not be applied. # # WARNING: # * If the reg ex specified below does not compile, then # glance-api service will not start. (Guide for reg ex python compiler used: # http://docs.python.org/2/library/re.html#regular-expression-syntax) # * If an operation(create, read, update, delete) is not specified or misspelt # then the glance-api service will not start. # So, remember, with GREAT POWER comes GREAT RESPONSIBILITY! # # NOTE: Multiple roles can be specified for a given operation. These roles must # be comma separated. [^x_.*] create = admin,member read = admin,member update = admin,member delete = admin,member [.*] create = admin read = admin update = admin delete = admin glance-2014.1/etc/policy.json0000664000175400017540000000114312323736226017142 0ustar jenkinsjenkins00000000000000{ "context_is_admin": "role:admin", "default": "", "add_image": "", "delete_image": "", "get_image": "", "get_images": "", "modify_image": "", "publicize_image": "", "copy_from": "", "download_image": "", "upload_image": "", "delete_image_location": "", "get_image_location": "", "set_image_location": "", "add_member": "", "delete_member": "", "get_member": "", "get_members": "", "modify_member": "", "manage_image_cache": "role:admin", "get_task": "", "get_tasks": "", "add_task": "", "modify_task": "" } glance-2014.1/etc/schema-image.json0000664000175400017540000000235312323736226020167 0ustar jenkinsjenkins00000000000000{ "kernel_id": { "type": "string", "pattern": "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}$", "description": "ID of image stored in Glance that should be used as the kernel when booting an AMI-style image." }, "ramdisk_id": { "type": "string", "pattern": "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}$", "description": "ID of image stored in Glance that should be used as the ramdisk when booting an AMI-style image." }, "instance_uuid": { "type": "string", "description": "ID of instance used to create this image." }, "architecture": { "description": "Operating system architecture as specified in http://docs.openstack.org/trunk/openstack-compute/admin/content/adding-images.html", "type": "string" }, "os_distro": { "description": "Common name of operating system distribution as specified in http://docs.openstack.org/trunk/openstack-compute/admin/content/adding-images.html", "type": "string" }, "os_version": { "description": "Operating system version as specified by the distributor", "type": "string" } } glance-2014.1/glance.egg-info/0000775000175400017540000000000012323736427017124 5ustar jenkinsjenkins00000000000000glance-2014.1/glance.egg-info/dependency_links.txt0000664000175400017540000000000112323736427023172 0ustar jenkinsjenkins00000000000000 glance-2014.1/glance.egg-info/not-zip-safe0000664000175400017540000000000112323736422021345 0ustar jenkinsjenkins00000000000000 glance-2014.1/glance.egg-info/PKG-INFO0000664000175400017540000000215612323736427020225 0ustar jenkinsjenkins00000000000000Metadata-Version: 1.1 Name: glance Version: 2014.1 Summary: OpenStack Image Service Home-page: http://www.openstack.org/ Author: OpenStack Author-email: openstack-dev@lists.openstack.org License: UNKNOWN Description: ====== Glance ====== Glance is a project that defines services for discovering, registering, retrieving and storing virtual machine images. Use the following resources to learn more: * `Official Glance documentation `_ * `Official Client documentation `_ Platform: UNKNOWN Classifier: Environment :: OpenStack Classifier: Intended Audience :: Information Technology Classifier: Intended Audience :: System Administrators Classifier: License :: OSI Approved :: Apache Software License Classifier: Operating System :: POSIX :: Linux Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 2.6 glance-2014.1/glance.egg-info/entry_points.txt0000664000175400017540000000123212323736427022420 0ustar jenkinsjenkins00000000000000[console_scripts] glance-api = glance.cmd.api:main glance-cache-cleaner = glance.cmd.cache_cleaner:main glance-cache-manage = glance.cmd.cache_manage:main glance-cache-prefetcher = glance.cmd.cache_prefetcher:main glance-cache-pruner = glance.cmd.cache_pruner:main glance-control = glance.cmd.control:main glance-manage = glance.cmd.manage:main glance-registry = glance.cmd.registry:main glance-replicator = glance.cmd.replicator:main glance-scrubber = glance.cmd.scrubber:main [glance.common.image_location_strategy.modules] location_order_strategy = glance.common.location_strategy.location_order store_type_strategy = glance.common.location_strategy.store_type glance-2014.1/glance.egg-info/top_level.txt0000664000175400017540000000000712323736427021653 0ustar jenkinsjenkins00000000000000glance glance-2014.1/glance.egg-info/requires.txt0000664000175400017540000000076312323736427021532 0ustar jenkinsjenkins00000000000000pbr>=0.6,<1.0 greenlet>=0.3.2 SQLAlchemy>=0.7.8,<=0.9.99 anyjson>=0.3.3 eventlet>=0.13.0 PasteDeploy>=1.5.0 Routes>=1.12.3 WebOb>=1.2.3 boto>=2.12.0,!=2.13.0 sqlalchemy-migrate>=0.8.2,!=0.8.4 httplib2>=0.7.5 kombu>=2.4.8 pycrypto>=2.6 iso8601>=0.1.9 oslo.config>=1.2.0 stevedore>=0.14 python-swiftclient>=1.6 oslo.vmware>=0.2 # Apache-2.0 Paste jsonschema>=2.0.0,<3.0.0 python-cinderclient>=1.0.6 python-keystoneclient>=0.7.0 pyOpenSSL>=0.11 six>=1.5.2 oslo.messaging>=1.3.0a9glance-2014.1/glance.egg-info/SOURCES.txt0000664000175400017540000004144712323736427021022 0ustar jenkinsjenkins00000000000000.coveragerc .mailmap .testr.conf AUTHORS ChangeLog HACKING.rst LICENSE MANIFEST.in README.rst babel.cfg openstack-common.conf pylintrc requirements.txt run_tests.sh setup.cfg setup.py test-requirements.txt tox.ini doc/source/authentication.rst doc/source/cache.rst doc/source/common-image-properties.rst doc/source/conf.py doc/source/configuring.rst doc/source/controllingservers.rst doc/source/db.rst doc/source/formats.rst doc/source/glanceapi.rst doc/source/glanceclient.rst doc/source/identifiers.rst doc/source/index.rst doc/source/installing.rst doc/source/notifications.rst doc/source/policies.rst doc/source/property-protections.rst doc/source/statuses.rst doc/source/images/image_status_transition.png doc/source/images_src/image_status_transition.dot doc/source/man/footer.rst doc/source/man/general_options.rst doc/source/man/glanceapi.rst doc/source/man/glancecachecleaner.rst doc/source/man/glancecachemanage.rst doc/source/man/glancecacheprefetcher.rst doc/source/man/glancecachepruner.rst doc/source/man/glancecontrol.rst doc/source/man/glancemanage.rst doc/source/man/glanceregistry.rst doc/source/man/glancereplicator.rst doc/source/man/glancescrubber.rst doc/source/man/openstack_options.rst etc/glance-api-paste.ini etc/glance-api.conf etc/glance-cache.conf etc/glance-registry-paste.ini etc/glance-registry.conf etc/glance-scrubber.conf etc/logging.cnf.sample etc/policy.json etc/property-protections-policies.conf.sample etc/property-protections-roles.conf.sample etc/schema-image.json glance/__init__.py glance/context.py glance/gateway.py glance/notifier.py glance/schema.py glance/scrubber.py glance/version.py glance.egg-info/PKG-INFO glance.egg-info/SOURCES.txt glance.egg-info/dependency_links.txt glance.egg-info/entry_points.txt glance.egg-info/not-zip-safe glance.egg-info/requires.txt glance.egg-info/top_level.txt glance/api/__init__.py glance/api/authorization.py glance/api/cached_images.py glance/api/common.py glance/api/policy.py glance/api/property_protections.py glance/api/versions.py glance/api/middleware/__init__.py glance/api/middleware/cache.py glance/api/middleware/cache_manage.py glance/api/middleware/context.py glance/api/middleware/gzip.py glance/api/middleware/version_negotiation.py glance/api/v1/__init__.py glance/api/v1/controller.py glance/api/v1/filters.py glance/api/v1/images.py glance/api/v1/members.py glance/api/v1/router.py glance/api/v1/upload_utils.py glance/api/v2/__init__.py glance/api/v2/image_data.py glance/api/v2/image_members.py glance/api/v2/image_tags.py glance/api/v2/images.py glance/api/v2/router.py glance/api/v2/schemas.py glance/api/v2/tasks.py glance/cmd/__init__.py glance/cmd/api.py glance/cmd/cache_cleaner.py glance/cmd/cache_manage.py glance/cmd/cache_prefetcher.py glance/cmd/cache_pruner.py glance/cmd/control.py glance/cmd/manage.py glance/cmd/registry.py glance/cmd/replicator.py glance/cmd/scrubber.py glance/common/__init__.py glance/common/auth.py glance/common/client.py glance/common/config.py glance/common/crypt.py glance/common/exception.py glance/common/property_utils.py glance/common/rpc.py glance/common/utils.py glance/common/wsgi.py glance/common/location_strategy/__init__.py glance/common/location_strategy/location_order.py glance/common/location_strategy/store_type.py glance/db/__init__.py glance/db/migration.py glance/db/registry/__init__.py glance/db/registry/api.py glance/db/simple/__init__.py glance/db/simple/api.py glance/db/sqlalchemy/__init__.py glance/db/sqlalchemy/api.py glance/db/sqlalchemy/models.py glance/db/sqlalchemy/migrate_repo/README glance/db/sqlalchemy/migrate_repo/__init__.py glance/db/sqlalchemy/migrate_repo/manage.py glance/db/sqlalchemy/migrate_repo/migrate.cfg glance/db/sqlalchemy/migrate_repo/schema.py glance/db/sqlalchemy/migrate_repo/versions/001_add_images_table.py glance/db/sqlalchemy/migrate_repo/versions/002_add_image_properties_table.py glance/db/sqlalchemy/migrate_repo/versions/003_add_disk_format.py glance/db/sqlalchemy/migrate_repo/versions/003_sqlite_downgrade.sql glance/db/sqlalchemy/migrate_repo/versions/003_sqlite_upgrade.sql glance/db/sqlalchemy/migrate_repo/versions/004_add_checksum.py glance/db/sqlalchemy/migrate_repo/versions/005_size_big_integer.py glance/db/sqlalchemy/migrate_repo/versions/006_key_to_name.py glance/db/sqlalchemy/migrate_repo/versions/006_mysql_downgrade.sql glance/db/sqlalchemy/migrate_repo/versions/006_mysql_upgrade.sql glance/db/sqlalchemy/migrate_repo/versions/006_sqlite_downgrade.sql glance/db/sqlalchemy/migrate_repo/versions/006_sqlite_upgrade.sql glance/db/sqlalchemy/migrate_repo/versions/007_add_owner.py glance/db/sqlalchemy/migrate_repo/versions/008_add_image_members_table.py glance/db/sqlalchemy/migrate_repo/versions/009_add_mindisk_and_minram.py glance/db/sqlalchemy/migrate_repo/versions/010_default_update_at.py glance/db/sqlalchemy/migrate_repo/versions/011_make_mindisk_and_minram_notnull.py glance/db/sqlalchemy/migrate_repo/versions/011_sqlite_downgrade.sql glance/db/sqlalchemy/migrate_repo/versions/011_sqlite_upgrade.sql glance/db/sqlalchemy/migrate_repo/versions/012_id_to_uuid.py glance/db/sqlalchemy/migrate_repo/versions/013_add_protected.py glance/db/sqlalchemy/migrate_repo/versions/013_sqlite_downgrade.sql glance/db/sqlalchemy/migrate_repo/versions/014_add_image_tags_table.py glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py glance/db/sqlalchemy/migrate_repo/versions/016_add_status_image_member.py glance/db/sqlalchemy/migrate_repo/versions/016_sqlite_downgrade.sql glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py glance/db/sqlalchemy/migrate_repo/versions/018_add_image_locations_table.py glance/db/sqlalchemy/migrate_repo/versions/019_migrate_image_locations.py glance/db/sqlalchemy/migrate_repo/versions/020_drop_images_table_location.py glance/db/sqlalchemy/migrate_repo/versions/021_set_engine_mysql_innodb.py glance/db/sqlalchemy/migrate_repo/versions/022_image_member_index.py glance/db/sqlalchemy/migrate_repo/versions/023_placeholder.py glance/db/sqlalchemy/migrate_repo/versions/024_placeholder.py glance/db/sqlalchemy/migrate_repo/versions/025_placeholder.py glance/db/sqlalchemy/migrate_repo/versions/026_add_location_storage_information.py glance/db/sqlalchemy/migrate_repo/versions/027_checksum_index.py glance/db/sqlalchemy/migrate_repo/versions/028_owner_index.py glance/db/sqlalchemy/migrate_repo/versions/029_location_meta_data_pickle_to_string.py glance/db/sqlalchemy/migrate_repo/versions/030_add_tasks_table.py glance/db/sqlalchemy/migrate_repo/versions/031_remove_duplicated_locations.py glance/db/sqlalchemy/migrate_repo/versions/032_add_task_info_table.py glance/db/sqlalchemy/migrate_repo/versions/033_add_location_status.py glance/db/sqlalchemy/migrate_repo/versions/034_add_virtual_size.py glance/db/sqlalchemy/migrate_repo/versions/__init__.py glance/domain/__init__.py glance/domain/proxy.py glance/image_cache/__init__.py glance/image_cache/base.py glance/image_cache/cleaner.py glance/image_cache/client.py glance/image_cache/prefetcher.py glance/image_cache/pruner.py glance/image_cache/drivers/__init__.py glance/image_cache/drivers/base.py glance/image_cache/drivers/sqlite.py glance/image_cache/drivers/xattr.py glance/locale/glance.pot glance/locale/ar/LC_MESSAGES/glance.po glance/locale/bg_BG/LC_MESSAGES/glance.po glance/locale/bn_IN/LC_MESSAGES/glance.po glance/locale/bs/LC_MESSAGES/glance.po glance/locale/ca/LC_MESSAGES/glance.po glance/locale/cs/LC_MESSAGES/glance.po glance/locale/da/LC_MESSAGES/glance.po glance/locale/de/LC_MESSAGES/glance.po glance/locale/el/LC_MESSAGES/glance.po glance/locale/en_AU/LC_MESSAGES/glance.po glance/locale/en_GB/LC_MESSAGES/glance.po glance/locale/en_US/LC_MESSAGES/glance.po glance/locale/es/LC_MESSAGES/glance.po glance/locale/es_MX/LC_MESSAGES/glance.po glance/locale/eu/LC_MESSAGES/glance.po glance/locale/eu_ES/LC_MESSAGES/glance.po glance/locale/fa/LC_MESSAGES/glance.po glance/locale/fi_FI/LC_MESSAGES/glance.po glance/locale/fil/LC_MESSAGES/glance.po glance/locale/fr/LC_MESSAGES/glance.po glance/locale/gl/LC_MESSAGES/glance.po glance/locale/he/LC_MESSAGES/glance.po glance/locale/he_IL/LC_MESSAGES/glance.po glance/locale/hi/LC_MESSAGES/glance.po glance/locale/hr/LC_MESSAGES/glance.po glance/locale/hu/LC_MESSAGES/glance.po glance/locale/id/LC_MESSAGES/glance.po glance/locale/is_IS/LC_MESSAGES/glance.po glance/locale/it/LC_MESSAGES/glance.po glance/locale/it_IT/LC_MESSAGES/glance.po glance/locale/ja/LC_MESSAGES/glance.po glance/locale/ka_GE/LC_MESSAGES/glance.po glance/locale/km/LC_MESSAGES/glance.po glance/locale/kn/LC_MESSAGES/glance.po glance/locale/ko/LC_MESSAGES/glance.po glance/locale/ko_KR/LC_MESSAGES/glance.po glance/locale/ml_IN/LC_MESSAGES/glance.po glance/locale/mr_IN/LC_MESSAGES/glance.po glance/locale/ms/LC_MESSAGES/glance.po glance/locale/nb/LC_MESSAGES/glance.po glance/locale/ne/LC_MESSAGES/glance.po glance/locale/nl_NL/LC_MESSAGES/glance.po glance/locale/pa_IN/LC_MESSAGES/glance.po glance/locale/pl_PL/LC_MESSAGES/glance.po glance/locale/pt/LC_MESSAGES/glance.po glance/locale/pt_BR/LC_MESSAGES/glance.po glance/locale/ro/LC_MESSAGES/glance.po glance/locale/ru/LC_MESSAGES/glance.po glance/locale/ru_RU/LC_MESSAGES/glance.po glance/locale/sk/LC_MESSAGES/glance.po glance/locale/sl_SI/LC_MESSAGES/glance.po glance/locale/sq/LC_MESSAGES/glance.po glance/locale/sr/LC_MESSAGES/glance.po glance/locale/sv/LC_MESSAGES/glance.po glance/locale/sw_KE/LC_MESSAGES/glance.po glance/locale/ta/LC_MESSAGES/glance.po glance/locale/te_IN/LC_MESSAGES/glance.po glance/locale/tl/LC_MESSAGES/glance.po glance/locale/tl_PH/LC_MESSAGES/glance.po glance/locale/tr/LC_MESSAGES/glance.po glance/locale/tr_TR/LC_MESSAGES/glance.po glance/locale/uk/LC_MESSAGES/glance.po glance/locale/ur/LC_MESSAGES/glance.po glance/locale/vi_VN/LC_MESSAGES/glance.po glance/locale/zh_CN/LC_MESSAGES/glance.po glance/locale/zh_HK/LC_MESSAGES/glance.po glance/locale/zh_TW/LC_MESSAGES/glance.po glance/openstack/__init__.py glance/openstack/common/README glance/openstack/common/__init__.py glance/openstack/common/eventlet_backdoor.py glance/openstack/common/excutils.py glance/openstack/common/fileutils.py glance/openstack/common/gettextutils.py glance/openstack/common/importutils.py glance/openstack/common/jsonutils.py glance/openstack/common/local.py glance/openstack/common/lockutils.py glance/openstack/common/log.py glance/openstack/common/loopingcall.py glance/openstack/common/network_utils.py glance/openstack/common/policy.py glance/openstack/common/processutils.py glance/openstack/common/service.py glance/openstack/common/strutils.py glance/openstack/common/test.py glance/openstack/common/threadgroup.py glance/openstack/common/timeutils.py glance/openstack/common/units.py glance/openstack/common/db/__init__.py glance/openstack/common/db/api.py glance/openstack/common/db/exception.py glance/openstack/common/db/options.py glance/openstack/common/db/sqlalchemy/__init__.py glance/openstack/common/db/sqlalchemy/migration.py glance/openstack/common/db/sqlalchemy/models.py glance/openstack/common/db/sqlalchemy/provision.py glance/openstack/common/db/sqlalchemy/session.py glance/openstack/common/db/sqlalchemy/test_base.py glance/openstack/common/db/sqlalchemy/test_migrations.conf glance/openstack/common/db/sqlalchemy/test_migrations.py glance/openstack/common/db/sqlalchemy/utils.py glance/quota/__init__.py glance/registry/__init__.py glance/registry/api/__init__.py glance/registry/api/v1/__init__.py glance/registry/api/v1/images.py glance/registry/api/v1/members.py glance/registry/api/v2/__init__.py glance/registry/api/v2/rpc.py glance/registry/client/__init__.py glance/registry/client/v1/__init__.py glance/registry/client/v1/api.py glance/registry/client/v1/client.py glance/registry/client/v2/__init__.py glance/registry/client/v2/api.py glance/registry/client/v2/client.py glance/store/__init__.py glance/store/base.py glance/store/cinder.py glance/store/filesystem.py glance/store/gridfs.py glance/store/http.py glance/store/location.py glance/store/rbd.py glance/store/s3.py glance/store/sheepdog.py glance/store/swift.py glance/store/vmware_datastore.py glance/tests/__init__.py glance/tests/stubs.py glance/tests/utils.py glance/tests/etc/policy.json glance/tests/etc/property-protections-policies.conf glance/tests/etc/property-protections.conf glance/tests/etc/schema-image.json glance/tests/functional/__init__.py glance/tests/functional/store_utils.py glance/tests/functional/test_api.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_glance_manage.py glance/tests/functional/test_gzip_middleware.py glance/tests/functional/test_logging.py glance/tests/functional/test_scrubber.py glance/tests/functional/test_sqlite.py glance/tests/functional/db/__init__.py glance/tests/functional/db/base.py glance/tests/functional/db/test_registry.py glance/tests/functional/db/test_rpc_endpoint.py glance/tests/functional/db/test_simple.py glance/tests/functional/db/test_sqlalchemy.py glance/tests/functional/store/__init__.py glance/tests/functional/store/test_cinder.py glance/tests/functional/store/test_filesystem.py glance/tests/functional/store/test_gridfs.py glance/tests/functional/store/test_http.py glance/tests/functional/store/test_rbd.py glance/tests/functional/store/test_s3.py glance/tests/functional/store/test_sheepdog.py glance/tests/functional/store/test_swift.py glance/tests/functional/store/test_vmware_datastore.py glance/tests/functional/v1/__init__.py glance/tests/functional/v1/test_api.py glance/tests/functional/v1/test_copy_to_file.py glance/tests/functional/v1/test_misc.py glance/tests/functional/v1/test_multiprocessing.py glance/tests/functional/v1/test_ssl.py glance/tests/functional/v2/__init__.py glance/tests/functional/v2/test_images.py glance/tests/functional/v2/test_schemas.py glance/tests/functional/v2/test_tasks.py glance/tests/integration/__init__.py glance/tests/integration/legacy_functional/__init__.py glance/tests/integration/legacy_functional/base.py glance/tests/integration/legacy_functional/test_v1_api.py glance/tests/integration/v2/__init__.py glance/tests/integration/v2/base.py glance/tests/integration/v2/test_tasks_api.py glance/tests/unit/__init__.py glance/tests/unit/base.py glance/tests/unit/fake_rados.py glance/tests/unit/test_auth.py glance/tests/unit/test_cache_middleware.py glance/tests/unit/test_cached_images.py glance/tests/unit/test_cinder_store.py glance/tests/unit/test_context.py glance/tests/unit/test_context_middleware.py glance/tests/unit/test_db.py glance/tests/unit/test_domain.py glance/tests/unit/test_domain_proxy.py glance/tests/unit/test_filesystem_store.py glance/tests/unit/test_glance_replicator.py glance/tests/unit/test_gridfs_store.py glance/tests/unit/test_http_store.py glance/tests/unit/test_image_cache.py glance/tests/unit/test_image_cache_client.py glance/tests/unit/test_manage.py glance/tests/unit/test_migrations.conf glance/tests/unit/test_migrations.py glance/tests/unit/test_misc.py glance/tests/unit/test_notifier.py glance/tests/unit/test_policy.py glance/tests/unit/test_quota.py glance/tests/unit/test_rbd_store.py glance/tests/unit/test_s3_store.py glance/tests/unit/test_schema.py glance/tests/unit/test_scrubber.py glance/tests/unit/test_sheepdog_store.py glance/tests/unit/test_store_base.py glance/tests/unit/test_store_image.py glance/tests/unit/test_store_location.py glance/tests/unit/test_swift_store.py glance/tests/unit/test_versions.py glance/tests/unit/test_vmware_store.py glance/tests/unit/utils.py glance/tests/unit/api/__init__.py glance/tests/unit/api/test_cmd.py glance/tests/unit/api/test_cmd_cache_manage.py glance/tests/unit/api/test_common.py glance/tests/unit/api/test_property_protections.py glance/tests/unit/api/middleware/__init__.py glance/tests/unit/api/middleware/test_cache_manage.py glance/tests/unit/common/__init__.py glance/tests/unit/common/test_client.py glance/tests/unit/common/test_config.py glance/tests/unit/common/test_exception.py glance/tests/unit/common/test_location_strategy.py glance/tests/unit/common/test_property_utils.py glance/tests/unit/common/test_rpc.py glance/tests/unit/common/test_utils.py glance/tests/unit/common/test_wsgi.py glance/tests/unit/v1/__init__.py glance/tests/unit/v1/test_api.py glance/tests/unit/v1/test_registry_api.py glance/tests/unit/v1/test_registry_client.py glance/tests/unit/v1/test_upload_utils.py glance/tests/unit/v2/__init__.py glance/tests/unit/v2/test_image_data_resource.py glance/tests/unit/v2/test_image_members_resource.py glance/tests/unit/v2/test_image_tags_resource.py glance/tests/unit/v2/test_images_resource.py glance/tests/unit/v2/test_registry_api.py glance/tests/unit/v2/test_registry_client.py glance/tests/unit/v2/test_schemas_resource.py glance/tests/unit/v2/test_tasks_resource.py glance/tests/var/ca.crt glance/tests/var/certificate.crt glance/tests/var/privatekey.key tools/colorizer.py tools/install_venv.py tools/install_venv_common.py tools/migrate_image_owners.py tools/with_venv.shglance-2014.1/LICENSE0000664000175400017540000002363712323736226015216 0ustar jenkinsjenkins00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. glance-2014.1/babel.cfg0000664000175400017540000000002012323736226015714 0ustar jenkinsjenkins00000000000000[python: **.py] glance-2014.1/requirements.txt0000664000175400017540000000162712323736230017463 0ustar jenkinsjenkins00000000000000pbr>=0.6,<1.0 # # The greenlet package must be compiled with gcc and needs # the Python.h headers. Make sure you install the python-dev # package to get the right headers... greenlet>=0.3.2 # < 0.8.0/0.8 does not work, see https://bugs.launchpad.net/bugs/1153983 SQLAlchemy>=0.7.8,<=0.9.99 anyjson>=0.3.3 eventlet>=0.13.0 PasteDeploy>=1.5.0 Routes>=1.12.3 WebOb>=1.2.3 argparse boto>=2.12.0,!=2.13.0 sqlalchemy-migrate>=0.8.2,!=0.8.4 httplib2>=0.7.5 kombu>=2.4.8 pycrypto>=2.6 iso8601>=0.1.9 ordereddict oslo.config>=1.2.0 stevedore>=0.14 # For Swift storage backend. python-swiftclient>=1.6 # For VMware storage backed. oslo.vmware>=0.2 # Apache-2.0 # For paste.util.template used in keystone.common.template Paste jsonschema>=2.0.0,<3.0.0 python-cinderclient>=1.0.6 python-keystoneclient>=0.7.0 pyOpenSSL>=0.11 # Required by openstack.common libraries six>=1.5.2 oslo.messaging>=1.3.0a9 glance-2014.1/pylintrc0000664000175400017540000000145412323736226015771 0ustar jenkinsjenkins00000000000000[Messages Control] # W0511: TODOs in code comments are fine. # W0142: *args and **kwargs are fine. # W0622: Redefining id is fine. disable-msg=W0511,W0142,W0622 [Basic] # Variable names can be 1 to 31 characters long, with lowercase and underscores variable-rgx=[a-z_][a-z0-9_]{0,30}$ # Argument names can be 2 to 31 characters long, with lowercase and underscores argument-rgx=[a-z_][a-z0-9_]{1,30}$ # Method names should be at least 3 characters long # and be lowecased with underscores method-rgx=[a-z_][a-z0-9_]{2,50}$ # Module names matching nova-* are ok (files in bin/) module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+)|(nova-[a-z0-9_-]+))$ # Don't require docstrings on tests. no-docstring-rgx=((__.*__)|([tT]est.*)|setUp|tearDown)$ [Design] max-public-methods=100 min-public-methods=0 max-args=6 glance-2014.1/glance/0000775000175400017540000000000012323736427015432 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/domain/0000775000175400017540000000000012323736427016701 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/domain/proxy.py0000664000175400017540000001670212323736230020432 0ustar jenkinsjenkins00000000000000# Copyright 2013 OpenStack Foundation # Copyright 2013 IBM Corp. # 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. def _proxy(target, attr): def get_attr(self): return getattr(getattr(self, target), attr) def set_attr(self, value): return setattr(getattr(self, target), attr, value) def del_attr(self): return delattr(getattr(self, target), attr) return property(get_attr, set_attr, del_attr) class Helper(object): def __init__(self, proxy_class=None, proxy_kwargs=None): self.proxy_class = proxy_class self.proxy_kwargs = proxy_kwargs or {} def proxy(self, obj): if obj is None or self.proxy_class is None: return obj return self.proxy_class(obj, **self.proxy_kwargs) def unproxy(self, obj): if obj is None or self.proxy_class is None: return obj return obj.base class TaskRepo(object): def __init__(self, base, task_proxy_class=None, task_proxy_kwargs=None, task_details_proxy_class=None, task_details_proxy_kwargs=None): self.base = base self.task_proxy_helper = Helper(task_proxy_class, task_proxy_kwargs) self.task_details_proxy_helper = Helper(task_details_proxy_class, task_details_proxy_kwargs) def get_task_and_details(self, task_id): task, task_details = self.base.get_task_and_details(task_id) return (self.task_proxy_helper.proxy(task), self.task_details_proxy_helper.proxy(task_details)) def list_tasks(self, *args, **kwargs): tasks = self.base.list_tasks(*args, **kwargs) return [self.task_proxy_helper.proxy(task) for task in tasks] def add(self, task, task_details=None): self.base.add(self.task_proxy_helper.unproxy(task), self.task_details_proxy_helper.unproxy(task_details)) def save(self, task, task_details=None): self.base.save(self.task_proxy_helper.unproxy(task), self.task_details_proxy_helper.unproxy(task_details)) def remove(self, task): base_task = self.task_proxy_helper.unproxy(task) self.base.remove(base_task) class Repo(object): def __init__(self, base, item_proxy_class=None, item_proxy_kwargs=None): self.base = base self.helper = Helper(item_proxy_class, item_proxy_kwargs) def get(self, item_id): return self.helper.proxy(self.base.get(item_id)) def list(self, *args, **kwargs): items = self.base.list(*args, **kwargs) return [self.helper.proxy(item) for item in items] def add(self, item): base_item = self.helper.unproxy(item) result = self.base.add(base_item) return self.helper.proxy(result) def save(self, item): base_item = self.helper.unproxy(item) result = self.base.save(base_item) return self.helper.proxy(result) def remove(self, item): base_item = self.helper.unproxy(item) result = self.base.remove(base_item) return self.helper.proxy(result) class ImageFactory(object): def __init__(self, base, proxy_class=None, proxy_kwargs=None): self.helper = Helper(proxy_class, proxy_kwargs) self.base = base def new_image(self, **kwargs): return self.helper.proxy(self.base.new_image(**kwargs)) class ImageMembershipFactory(object): def __init__(self, base, image_proxy_class=None, image_proxy_kwargs=None, member_proxy_class=None, member_proxy_kwargs=None): self.base = base self.image_helper = Helper(image_proxy_class, image_proxy_kwargs) self.member_helper = Helper(member_proxy_class, member_proxy_kwargs) def new_image_member(self, image, member_id): base_image = self.image_helper.unproxy(image) member = self.base.new_image_member(base_image, member_id) return self.member_helper.proxy(member) class Image(object): def __init__(self, base, member_repo_proxy_class=None, member_repo_proxy_kwargs=None): self.base = base self.helper = Helper(member_repo_proxy_class, member_repo_proxy_kwargs) name = _proxy('base', 'name') image_id = _proxy('base', 'image_id') name = _proxy('base', 'name') status = _proxy('base', 'status') created_at = _proxy('base', 'created_at') updated_at = _proxy('base', 'updated_at') visibility = _proxy('base', 'visibility') min_disk = _proxy('base', 'min_disk') min_ram = _proxy('base', 'min_ram') protected = _proxy('base', 'protected') locations = _proxy('base', 'locations') checksum = _proxy('base', 'checksum') owner = _proxy('base', 'owner') disk_format = _proxy('base', 'disk_format') container_format = _proxy('base', 'container_format') size = _proxy('base', 'size') virtual_size = _proxy('base', 'virtual_size') extra_properties = _proxy('base', 'extra_properties') tags = _proxy('base', 'tags') def delete(self): self.base.delete() def set_data(self, data, size=None): self.base.set_data(data, size) def get_data(self): return self.base.get_data() def get_member_repo(self): return self.helper.proxy(self.base.get_member_repo()) class Task(object): def __init__(self, base): self.base = base task_id = _proxy('base', 'task_id') type = _proxy('base', 'type') status = _proxy('base', 'status') owner = _proxy('base', 'owner') expires_at = _proxy('base', 'expires_at') created_at = _proxy('base', 'created_at') updated_at = _proxy('base', 'updated_at') def run(self, executor): self.base.run(executor) def begin_processing(self): self.base.begin_processing() def succeed(self, result): self.base.succeed(result) def fail(self, message): self.base.fail(message) class TaskDetails(object): def __init__(self, base): self.base = base task_id = _proxy('base', 'task_id') input = _proxy('base', 'input') result = _proxy('base', 'result') message = _proxy('base', 'message') class TaskFactory(object): def __init__(self, base, task_proxy_class=None, task_proxy_kwargs=None, task_details_proxy_class=None, task_details_proxy_kwargs=None): self.task_helper = Helper(task_proxy_class, task_proxy_kwargs) self.task_details_helper = Helper(task_details_proxy_class, task_details_proxy_kwargs) self.base = base def new_task(self, **kwargs): t = self.base.new_task(**kwargs) return self.task_helper.proxy(t) def new_task_details(self, task_id, task_input, message=None, result=None): td = self.base.new_task_details(task_id, task_input, message, result) return self.task_details_helper.proxy(td) glance-2014.1/glance/domain/__init__.py0000664000175400017540000003442412323736230021011 0ustar jenkinsjenkins00000000000000# Copyright 2012 OpenStack Foundation # Copyright 2013 IBM Corp. # 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 collections import datetime import uuid from oslo.config import cfg from glance.common import exception import glance.openstack.common.log as logging from glance.openstack.common import timeutils CONF = cfg.CONF LOG = logging.getLogger(__name__) _delayed_delete_imported = False def _import_delayed_delete(): # glance.store (indirectly) imports glance.domain therefore we can't put # the CONF.import_opt outside - we have to do it in a convoluted/indirect # way! global _delayed_delete_imported if not _delayed_delete_imported: CONF.import_opt('delayed_delete', 'glance.store') _delayed_delete_imported = True class ImageFactory(object): _readonly_properties = ['created_at', 'updated_at', 'status', 'checksum', 'size', 'virtual_size'] _reserved_properties = ['owner', 'is_public', 'locations', 'deleted', 'deleted_at', 'direct_url', 'self', 'file', 'schema'] def _check_readonly(self, kwargs): for key in self._readonly_properties: if key in kwargs: raise exception.ReadonlyProperty(property=key) def _check_unexpected(self, kwargs): if kwargs: msg = _('new_image() got unexpected keywords %s') raise TypeError(msg % kwargs.keys()) def _check_reserved(self, properties): if properties is not None: for key in self._reserved_properties: if key in properties: raise exception.ReservedProperty(property=key) def new_image(self, image_id=None, name=None, visibility='private', min_disk=0, min_ram=0, protected=False, owner=None, disk_format=None, container_format=None, extra_properties=None, tags=None, **other_args): self._check_readonly(other_args) self._check_unexpected(other_args) self._check_reserved(extra_properties) if image_id is None: image_id = str(uuid.uuid4()) created_at = timeutils.utcnow() updated_at = created_at status = 'queued' return Image(image_id=image_id, name=name, status=status, created_at=created_at, updated_at=updated_at, visibility=visibility, min_disk=min_disk, min_ram=min_ram, protected=protected, owner=owner, disk_format=disk_format, container_format=container_format, extra_properties=extra_properties, tags=tags) class Image(object): valid_state_targets = { # Each key denotes a "current" state for the image. Corresponding # values list the valid states to which we can jump from that "current" # state. # NOTE(flwang): In v2, we are deprecating the 'killed' status, so it's # allowed to restore image from 'saving' to 'queued' so that upload # can be retried. 'queued': ('saving', 'active', 'deleted'), 'saving': ('active', 'killed', 'deleted', 'queued'), 'active': ('queued', 'pending_delete', 'deleted'), 'killed': ('deleted'), 'pending_delete': ('deleted'), 'deleted': (), } def __init__(self, image_id, status, created_at, updated_at, **kwargs): self.image_id = image_id self.status = status self.created_at = created_at self.updated_at = updated_at self.name = kwargs.pop('name', None) self.visibility = kwargs.pop('visibility', 'private') self.min_disk = kwargs.pop('min_disk', 0) self.min_ram = kwargs.pop('min_ram', 0) self.protected = kwargs.pop('protected', False) self.locations = kwargs.pop('locations', []) self.checksum = kwargs.pop('checksum', None) self.owner = kwargs.pop('owner', None) self._disk_format = kwargs.pop('disk_format', None) self._container_format = kwargs.pop('container_format', None) self.size = kwargs.pop('size', None) self.virtual_size = kwargs.pop('virtual_size', None) extra_properties = kwargs.pop('extra_properties', None) or {} self.extra_properties = ExtraProperties(extra_properties) self.tags = kwargs.pop('tags', None) or [] if kwargs: message = _("__init__() got unexpected keyword argument '%s'") raise TypeError(message % kwargs.keys()[0]) @property def status(self): return self._status @status.setter def status(self, status): has_status = hasattr(self, '_status') if has_status: if status not in self.valid_state_targets[self._status]: kw = {'cur_status': self._status, 'new_status': status} e = exception.InvalidImageStatusTransition(**kw) LOG.debug(e) raise e if self._status == 'queued' and status in ('saving', 'active'): missing = [k for k in ['disk_format', 'container_format'] if not getattr(self, k)] if len(missing) > 0: if len(missing) == 1: msg = _('Property %s must be set prior to ' 'saving data.') else: msg = _('Properties %s must be set prior to ' 'saving data.') raise ValueError(msg % ', '.join(missing)) # NOTE(flwang): Image size should be cleared as long as the image # status is updated to 'queued' if status == 'queued': self.size = None self.virtual_size = None self._status = status @property def visibility(self): return self._visibility @visibility.setter def visibility(self, visibility): if visibility not in ('public', 'private'): raise ValueError(_('Visibility must be either "public" ' 'or "private"')) self._visibility = visibility @property def tags(self): return self._tags @tags.setter def tags(self, value): self._tags = set(value) @property def container_format(self): return self._container_format @container_format.setter def container_format(self, value): if hasattr(self, '_container_format') and self.status != 'queued': msg = _("Attribute container_format can be only replaced " "for a queued image.") raise exception.Forbidden(message=msg) self._container_format = value @property def disk_format(self): return self._disk_format @disk_format.setter def disk_format(self, value): if hasattr(self, '_disk_format') and self.status != 'queued': msg = _("Attribute disk_format can be only replaced " "for a queued image.") raise exception.Forbidden(message=msg) self._disk_format = value @property def min_disk(self): return self._min_disk @min_disk.setter def min_disk(self, value): if value and value < 0: extra_msg = _('Cannot be a negative value') raise exception.InvalidParameterValue(value=value, param='min_disk', extra_msg=extra_msg) self._min_disk = value @property def min_ram(self): return self._min_ram @min_ram.setter def min_ram(self, value): if value and value < 0: extra_msg = _('Cannot be a negative value') raise exception.InvalidParameterValue(value=value, param='min_ram', extra_msg=extra_msg) self._min_ram = value def delete(self): if self.protected: raise exception.ProtectedImageDelete(image_id=self.image_id) if CONF.delayed_delete and self.locations: self.status = 'pending_delete' else: self.status = 'deleted' def get_data(self): raise NotImplementedError() def set_data(self, data, size=None): raise NotImplementedError() class ExtraProperties(collections.MutableMapping, dict): def __getitem__(self, key): return dict.__getitem__(self, key) def __setitem__(self, key, value): return dict.__setitem__(self, key, value) def __delitem__(self, key): return dict.__delitem__(self, key) def __eq__(self, other): if isinstance(other, ExtraProperties): return dict(self).__eq__(dict(other)) elif isinstance(other, dict): return dict(self).__eq__(other) else: return False def __len__(self): return dict(self).__len__() def keys(self): return dict(self).keys() class ImageMembership(object): def __init__(self, image_id, member_id, created_at, updated_at, id=None, status=None): self.id = id self.image_id = image_id self.member_id = member_id self.created_at = created_at self.updated_at = updated_at self.status = status @property def status(self): return self._status @status.setter def status(self, status): if status not in ('pending', 'accepted', 'rejected'): msg = _('Status must be "pending", "accepted" or "rejected".') raise ValueError(msg) self._status = status class ImageMemberFactory(object): def new_image_member(self, image, member_id): created_at = timeutils.utcnow() updated_at = created_at return ImageMembership(image_id=image.image_id, member_id=member_id, created_at=created_at, updated_at=updated_at, status='pending') class Task(object): _supported_task_type = ('import',) _supported_task_status = ('pending', 'processing', 'success', 'failure') def __init__(self, task_id, task_type, status, owner, expires_at, created_at, updated_at, task_time_to_live=48): if task_type not in self._supported_task_type: raise exception.InvalidTaskType(task_type) if status not in self._supported_task_status: raise exception.InvalidTaskStatus(status) self.task_id = task_id self._status = status self.type = task_type self.owner = owner self.expires_at = expires_at # NOTE(nikhil): We use '_time_to_live' to determine how long a # task should live from the time it succeeds or fails. self._time_to_live = datetime.timedelta(hours=task_time_to_live) self.created_at = created_at self.updated_at = updated_at @property def status(self): return self._status def run(self, executor): pass def _validate_task_status_transition(self, cur_status, new_status): valid_transitions = { 'pending': ['processing', 'failure'], 'processing': ['success', 'failure'], 'success': [], 'failure': [], } if new_status in valid_transitions[cur_status]: return True else: return False def _set_task_status(self, new_status): if self._validate_task_status_transition(self.status, new_status): self._status = new_status log_msg = (_("Task status changed from %(cur_status)s to " "%(new_status)s") % {'cur_status': self.status, 'new_status': new_status}) LOG.info(log_msg) else: log_msg = (_("Task status failed to change from %(cur_status)s " "to %(new_status)s") % {'cur_status': self.status, 'new_status': new_status}) LOG.error(log_msg) raise exception.InvalidTaskStatusTransition( cur_status=self.status, new_status=new_status ) def begin_processing(self): new_status = 'processing' self._set_task_status(new_status) def succeed(self, result): new_status = 'success' self.result = result self._set_task_status(new_status) self.expires_at = timeutils.utcnow() + self._time_to_live def fail(self, message): new_status = 'failure' self.message = message self._set_task_status(new_status) self.expires_at = timeutils.utcnow() + self._time_to_live class TaskDetails(object): def __init__(self, task_id, task_input, message, result): if task_id is None: raise exception.TaskException(_('task_id is required to create ' 'a new TaskDetails object')) self.task_id = task_id self.input = task_input self.message = message self.result = result class TaskFactory(object): def new_task(self, task_type, owner, task_time_to_live=48): task_id = str(uuid.uuid4()) status = 'pending' # Note(nikhil): expires_at would be set on the task, only when it # succeeds or fails. expires_at = None created_at = timeutils.utcnow() updated_at = created_at return Task( task_id, task_type, status, owner, expires_at, created_at, updated_at, task_time_to_live ) def new_task_details(self, task_id, task_input, message=None, result=None): return TaskDetails(task_id, task_input, message, result) glance-2014.1/glance/store/0000775000175400017540000000000012323736427016566 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/store/sheepdog.py0000664000175400017540000002523712323736226020744 0ustar jenkinsjenkins00000000000000# Copyright 2013 Taobao 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. """Storage backend for Sheepdog storage system""" import hashlib from oslo.config import cfg from glance.common import exception from glance.common import utils from glance.openstack.common import excutils import glance.openstack.common.log as logging from glance.openstack.common import processutils from glance.openstack.common import units import glance.store import glance.store.base import glance.store.location LOG = logging.getLogger(__name__) DEFAULT_ADDR = '127.0.0.1' DEFAULT_PORT = 7000 DEFAULT_CHUNKSIZE = 64 # in MiB LOG = logging.getLogger(__name__) sheepdog_opts = [ cfg.IntOpt('sheepdog_store_chunk_size', default=DEFAULT_CHUNKSIZE, help=_('Images will be chunked into objects of this size ' '(in megabytes). For best performance, this should be ' 'a power of two.')), cfg.IntOpt('sheepdog_store_port', default=DEFAULT_PORT, help=_('Port of sheep daemon.')), cfg.StrOpt('sheepdog_store_address', default=DEFAULT_ADDR, help=_('IP address of sheep daemon.')) ] CONF = cfg.CONF CONF.register_opts(sheepdog_opts) class SheepdogImage: """Class describing an image stored in Sheepdog storage.""" def __init__(self, addr, port, name, chunk_size): self.addr = addr self.port = port self.name = name self.chunk_size = chunk_size def _run_command(self, command, data, *params): cmd = ["collie", "vdi"] cmd.extend(command) cmd.extend(["-a", self.addr, "-p", self.port, self.name]) cmd.extend(params) try: return processutils.execute(*cmd, process_input=data)[0] except (processutils.ProcessExecutionError, OSError) as exc: LOG.error(exc) raise glance.store.BackendException(exc) def get_size(self): """ Return the size of the this iamge Sheepdog Usage: collie vdi list -r -a address -p port image """ out = self._run_command(["list", "-r"], None) return long(out.split(' ')[3]) def read(self, offset, count): """ Read up to 'count' bytes from this image starting at 'offset' and return the data. Sheepdog Usage: collie vdi read -a address -p port image offset len """ return self._run_command(["read"], None, str(offset), str(count)) def write(self, data, offset, count): """ Write up to 'count' bytes from the data to this image starting at 'offset' Sheepdog Usage: collie vdi write -a address -p port image offset len """ self._run_command(["write"], data, str(offset), str(count)) def create(self, size): """ Create this image in the Sheepdog cluster with size 'size'. Sheepdog Usage: collie vdi create -a address -p port image size """ self._run_command(["create"], None, str(size)) def delete(self): """ Delete this image in the Sheepdog cluster Sheepdog Usage: collie vdi delete -a address -p port image """ self._run_command(["delete"], None) def exist(self): """ Check if this image exists in the Sheepdog cluster via 'list' command Sheepdog Usage: collie vdi list -r -a address -p port image """ out = self._run_command(["list", "-r"], None) if not out: return False else: return True class StoreLocation(glance.store.location.StoreLocation): """ Class describing a Sheepdog URI. This is of the form: sheepdog://image-id """ def process_specs(self): self.image = self.specs.get('image') def get_uri(self): return "sheepdog://%s" % self.image def parse_uri(self, uri): valid_schema = 'sheepdog://' if not uri.startswith(valid_schema): raise exception.BadStoreUri(_("URI must start with %s://") % valid_schema) self.image = uri[len(valid_schema):] if not utils.is_uuid_like(self.image): raise exception.BadStoreUri(_("URI must contains well-formated " "image id")) class ImageIterator(object): """ Reads data from an Sheepdog image, one chunk at a time. """ def __init__(self, image): self.image = image def __iter__(self): image = self.image total = left = image.get_size() while left > 0: length = min(image.chunk_size, left) data = image.read(total - left, length) left -= len(data) yield data raise StopIteration() class Store(glance.store.base.Store): """Sheepdog backend adapter.""" EXAMPLE_URL = "sheepdog://image" def get_schemes(self): return ('sheepdog',) def configure_add(self): """ Configure the Store to use the stored configuration options Any store that needs special configuration should implement this method. If the store was not able to successfully configure itself, it should raise `exception.BadStoreConfiguration` """ try: self.chunk_size = CONF.sheepdog_store_chunk_size * units.Mi self.addr = CONF.sheepdog_store_address.strip() self.port = CONF.sheepdog_store_port except cfg.ConfigFileValueError as e: reason = _("Error in store configuration: %s") % e LOG.error(reason) raise exception.BadStoreConfiguration(store_name='sheepdog', reason=reason) if ' ' in self.addr: reason = (_("Invalid address configuration of sheepdog store: %s") % self.addr) LOG.error(reason) raise exception.BadStoreConfiguration(store_name='sheepdog', reason=reason) try: cmd = ["collie", "vdi", "list", "-a", self.addr, "-p", self.port] processutils.execute(*cmd) except Exception as e: reason = _("Error in store configuration: %s") % e LOG.error(reason) raise exception.BadStoreConfiguration(store_name='sheepdog', reason=reason) def get(self, location): """ Takes a `glance.store.location.Location` object that indicates where to find the image file, and returns a generator for reading the image file :param location `glance.store.location.Location` object, supplied from glance.store.location.get_location_from_uri() :raises `glance.exception.NotFound` if image does not exist """ loc = location.store_location image = SheepdogImage(self.addr, self.port, loc.image, self.chunk_size) if not image.exist(): raise exception.NotFound(_("Sheepdog image %s does not exist") % image.name) return (ImageIterator(image), image.get_size()) def get_size(self, location): """ Takes a `glance.store.location.Location` object that indicates where to find the image file and returns the image size :param location `glance.store.location.Location` object, supplied from glance.store.location.get_location_from_uri() :raises `glance.exception.NotFound` if image does not exist :rtype int """ loc = location.store_location image = SheepdogImage(self.addr, self.port, loc.image, self.chunk_size) if not image.exist(): raise exception.NotFound(_("Sheepdog image %s does not exist") % image.name) return image.get_size() def add(self, image_id, image_file, image_size): """ Stores an image file with supplied identifier to the backend storage system and returns a tuple containing information about the stored image. :param image_id: The opaque image identifier :param image_file: The image data to write, as a file-like object :param image_size: The size of the image data to write, in bytes :retval tuple of URL in backing store, bytes written, and checksum :raises `glance.common.exception.Duplicate` if the image already existed """ image = SheepdogImage(self.addr, self.port, image_id, self.chunk_size) if image.exist(): raise exception.Duplicate(_("Sheepdog image %s already exists") % image_id) location = StoreLocation({'image': image_id}) checksum = hashlib.md5() image.create(image_size) try: total = left = image_size while left > 0: length = min(self.chunk_size, left) data = image_file.read(length) image.write(data, total - left, length) left -= length checksum.update(data) except Exception: # Note(zhiyan): clean up already received data when # error occurs such as ImageSizeLimitExceeded exception. with excutils.save_and_reraise_exception(): image.delete() return (location.get_uri(), image_size, checksum.hexdigest(), {}) def delete(self, location): """ Takes a `glance.store.location.Location` object that indicates where to find the image file to delete :location `glance.store.location.Location` object, supplied from glance.store.location.get_location_from_uri() :raises NotFound if image does not exist """ loc = location.store_location image = SheepdogImage(self.addr, self.port, loc.image, self.chunk_size) if not image.exist(): raise exception.NotFound(_("Sheepdog image %s does not exist") % loc.image) image.delete() glance-2014.1/glance/store/gridfs.py0000664000175400017540000001730312323736230020412 0ustar jenkinsjenkins00000000000000# Copyright 2013 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. """Storage backend for GridFS""" from __future__ import absolute_import from oslo.config import cfg import six.moves.urllib.parse as urlparse from glance.common import exception from glance.openstack.common import excutils import glance.openstack.common.log as logging import glance.store.base import glance.store.location try: import gridfs import gridfs.errors import pymongo import pymongo.uri_parser as uri_parser except ImportError: pymongo = None LOG = logging.getLogger(__name__) gridfs_opts = [ cfg.StrOpt('mongodb_store_uri', help="Hostname or IP address of the instance to connect to, " "or a mongodb URI, or a list of hostnames / mongodb URIs. " "If host is an IPv6 literal it must be enclosed " "in '[' and ']' characters following the RFC2732 " "URL syntax (e.g. '[::1]' for localhost)."), cfg.StrOpt('mongodb_store_db', default=None, help='Database to use.'), ] CONF = cfg.CONF CONF.register_opts(gridfs_opts) class StoreLocation(glance.store.location.StoreLocation): """ Class describing an gridfs URI: gridfs:// Connection information has been consciously omitted for security reasons, since this location will be stored in glance's database and can be queried from outside. Note(flaper87): Make connection info available if user wants so by adding a new configuration parameter `mongdb_store_insecure`. """ def get_uri(self): return "gridfs://%s" % self.specs.get("image_id") def parse_uri(self, uri): """ This method should fix any issue with the passed URI. Right now, it just sets image_id value in the specs dict. :param uri: Current set URI """ parsed = urlparse.urlparse(uri) assert parsed.scheme in ('gridfs',) self.specs["image_id"] = parsed.netloc class Store(glance.store.base.Store): """GridFS adapter""" EXAMPLE_URL = "gridfs://" def get_schemes(self): return ('gridfs',) def configure_add(self): """ Configure the Store to use the stored configuration options Any store that needs special configuration should implement this method. If the store was not able to successfully configure itself, it should raise `exception.BadStoreConfiguration` """ if pymongo is None: msg = _("Missing dependencies: pymongo") raise exception.BadStoreConfiguration(store_name="gridfs", reason=msg) self.mongodb_uri = self._option_get('mongodb_store_uri') parsed = uri_parser.parse_uri(self.mongodb_uri) self.mongodb_db = self._option_get('mongodb_store_db') or \ parsed.get("database") self.mongodb = pymongo.MongoClient(self.mongodb_uri) self.fs = gridfs.GridFS(self.mongodb[self.mongodb_db]) def _option_get(self, param): result = getattr(CONF, param) if not result: reason = (_("Could not find %(param)s in configuration " "options.") % {'param': param}) LOG.debug(reason) raise exception.BadStoreConfiguration(store_name="gridfs", reason=reason) return result def get(self, location): """ Takes a `glance.store.location.Location` object that indicates where to find the image file, and returns a tuple of generator (for reading the image file) and image_size :param location `glance.store.location.Location` object, supplied from glance.store.location.get_location_from_uri() :raises `glance.exception.NotFound` if image does not exist """ image = self._get_file(location) return (image, image.length) def get_size(self, location): """ Takes a `glance.store.location.Location` object that indicates where to find the image file, and returns the image_size (or 0 if unavailable) :param location `glance.store.location.Location` object, supplied from glance.store.location.get_location_from_uri() """ try: key = self._get_file(location) return key.length except Exception: return 0 def _get_file(self, location): store_location = location if isinstance(location, glance.store.location.Location): store_location = location.store_location try: parsed = urlparse.urlparse(store_location.get_uri()) return self.fs.get(parsed.netloc) except gridfs.errors.NoFile: msg = _("Could not find %s image in GridFS") % \ store_location.get_uri() LOG.debug(msg) raise exception.NotFound(msg) def add(self, image_id, image_file, image_size): """ Stores an image file with supplied identifier to the backend storage system and returns a tuple containing information about the stored image. :param image_id: The opaque image identifier :param image_file: The image data to write, as a file-like object :param image_size: The size of the image data to write, in bytes :retval tuple of URL in backing store, bytes written, checksum and a dictionary with storage system specific information :raises `glance.common.exception.Duplicate` if the image already existed """ loc = StoreLocation({'image_id': image_id}) if self.fs.exists(image_id): raise exception.Duplicate(_("GridFS already has an image at " "location %s") % loc.get_uri()) LOG.debug(_("Adding a new image to GridFS with id %(id)s and " "size %(size)s") % {'id': image_id, 'size': image_size}) try: self.fs.put(image_file, _id=image_id) image = self._get_file(loc) except Exception: # Note(zhiyan): clean up already received data when # error occurs such as ImageSizeLimitExceeded exception. with excutils.save_and_reraise_exception(): self.fs.delete(image_id) LOG.debug(_("Uploaded image %(id)s, md5 %(md5)s, length %(length)s " "to GridFS") % {'id': image._id, 'md5': image.md5, 'length': image.length}) return (loc.get_uri(), image.length, image.md5, {}) def delete(self, location): """ Takes a `glance.store.location.Location` object that indicates where to find the image file to delete :location `glance.store.location.Location` object, supplied from glance.store.location.get_location_from_uri() :raises NotFound if image does not exist """ image = self._get_file(location) self.fs.delete(image._id) LOG.debug("Deleted image %s from GridFS") glance-2014.1/glance/store/swift.py0000664000175400017540000007526612323736226020311 0ustar jenkinsjenkins00000000000000# Copyright 2010-2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """Storage backend for SWIFT""" from __future__ import absolute_import import hashlib import httplib import math from oslo.config import cfg import six.moves.urllib.parse as urlparse from glance.common import auth from glance.common import exception from glance.openstack.common import excutils import glance.openstack.common.log as logging import glance.store import glance.store.base import glance.store.location try: import swiftclient except ImportError: pass LOG = logging.getLogger(__name__) DEFAULT_CONTAINER = 'glance' DEFAULT_LARGE_OBJECT_SIZE = 5 * 1024 # 5GB DEFAULT_LARGE_OBJECT_CHUNK_SIZE = 200 # 200M ONE_MB = 1000 * 1024 swift_opts = [ cfg.BoolOpt('swift_enable_snet', default=False, help=_('Whether to use ServiceNET to communicate with the ' 'Swift storage servers.')), cfg.StrOpt('swift_store_auth_address', help=_('The address where the Swift authentication service ' 'is listening.')), cfg.StrOpt('swift_store_user', secret=True, help=_('The user to authenticate against the Swift ' 'authentication service.')), cfg.StrOpt('swift_store_key', secret=True, help=_('Auth key for the user authenticating against the ' 'Swift authentication service.')), cfg.StrOpt('swift_store_auth_version', default='2', help=_('Version of the authentication service to use. ' 'Valid versions are 2 for keystone and 1 for swauth ' 'and rackspace.')), cfg.BoolOpt('swift_store_auth_insecure', default=False, help=_('If True, swiftclient won\'t check for a valid SSL ' 'certificate when authenticating.')), cfg.StrOpt('swift_store_region', help=_('The region of the swift endpoint to be used for ' 'single tenant. This setting is only necessary if the ' 'tenant has multiple swift endpoints.')), cfg.StrOpt('swift_store_endpoint_type', default='publicURL', help=_('A string giving the endpoint type of the swift ' 'service to use (publicURL, adminURL or internalURL). ' 'This setting is only used if swift_store_auth_version ' 'is 2.')), cfg.StrOpt('swift_store_service_type', default='object-store', help=_('A string giving the service type of the swift service ' 'to use. This setting is only used if ' 'swift_store_auth_version is 2.')), cfg.StrOpt('swift_store_container', default=DEFAULT_CONTAINER, help=_('Container within the account that the account should ' 'use for storing images in Swift.')), cfg.IntOpt('swift_store_large_object_size', default=DEFAULT_LARGE_OBJECT_SIZE, help=_('The size, in MB, that Glance will start chunking image ' 'files and do a large object manifest in Swift.')), cfg.IntOpt('swift_store_large_object_chunk_size', default=DEFAULT_LARGE_OBJECT_CHUNK_SIZE, help=_('The amount of data written to a temporary disk buffer ' 'during the process of chunking the image file.')), cfg.BoolOpt('swift_store_create_container_on_put', default=False, help=_('A boolean value that determines if we create the ' 'container if it does not exist.')), cfg.BoolOpt('swift_store_multi_tenant', default=False, help=_('If set to True, enables multi-tenant storage ' 'mode which causes Glance images to be stored in ' 'tenant specific Swift accounts.')), cfg.ListOpt('swift_store_admin_tenants', default=[], help=_('A list of tenants that will be granted read/write ' 'access on all Swift containers created by Glance in ' 'multi-tenant mode.')), cfg.BoolOpt('swift_store_ssl_compression', default=True, help=_('If set to False, disables SSL layer compression of ' 'https swift requests. Setting to False may improve ' 'performance for images which are already in a ' 'compressed format, eg qcow2.')), cfg.IntOpt('swift_store_retry_get_count', default=0, help=_('The number of times a Swift download will be retried ' 'before the request fails.')) ] CONF = cfg.CONF CONF.register_opts(swift_opts) def swift_retry_iter(resp_iter, length, store, location): length = length if length else (resp_iter.len if hasattr(resp_iter, 'len') else 0) retries = 0 bytes_read = 0 while retries <= CONF.swift_store_retry_get_count: try: for chunk in resp_iter: yield chunk bytes_read += len(chunk) except swiftclient.ClientException as e: LOG.warn(_("Swift exception raised %s") % e) if bytes_read != length: if retries == CONF.swift_store_retry_get_count: # terminate silently and let higher level decide LOG.error(_("Stopping Swift retries after %d " "attempts") % retries) break else: retries += 1 LOG.info(_("Retrying Swift connection " "(%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d") % {'retries': retries, 'max_retries': CONF.swift_store_retry_get_count, 'start': bytes_read, 'end': length}) (resp_headers, resp_iter) = store._get_object(location, None, bytes_read) else: break class StoreLocation(glance.store.location.StoreLocation): """ Class describing a Swift URI. A Swift URI can look like any of the following: swift://user:pass@authurl.com/container/obj-id swift://account:user:pass@authurl.com/container/obj-id swift+http://user:pass@authurl.com/container/obj-id swift+https://user:pass@authurl.com/container/obj-id When using multi-tenant a URI might look like this (a storage URL): swift+https://example.com/container/obj-id The swift+http:// URIs indicate there is an HTTP authentication URL. The default for Swift is an HTTPS authentication URL, so swift:// and swift+https:// are the same... """ def process_specs(self): self.scheme = self.specs.get('scheme', 'swift+https') self.user = self.specs.get('user') self.key = self.specs.get('key') self.auth_or_store_url = self.specs.get('auth_or_store_url') self.container = self.specs.get('container') self.obj = self.specs.get('obj') def _get_credstring(self): if self.user and self.key: return '%s:%s@' % (urlparse.quote(self.user), urlparse.quote(self.key)) return '' def get_uri(self): auth_or_store_url = self.auth_or_store_url if auth_or_store_url.startswith('http://'): auth_or_store_url = auth_or_store_url[len('http://'):] elif auth_or_store_url.startswith('https://'): auth_or_store_url = auth_or_store_url[len('https://'):] credstring = self._get_credstring() auth_or_store_url = auth_or_store_url.strip('/') container = self.container.strip('/') obj = self.obj.strip('/') return '%s://%s%s/%s/%s' % (self.scheme, credstring, auth_or_store_url, container, obj) def parse_uri(self, uri): """ Parse URLs. This method fixes an issue where credentials specified in the URL are interpreted differently in Python 2.6.1+ than prior versions of Python. It also deals with the peculiarity that new-style Swift URIs have where a username can contain a ':', like so: swift://account:user:pass@authurl.com/container/obj """ # Make sure that URIs that contain multiple schemes, such as: # swift://user:pass@http://authurl.com/v1/container/obj # are immediately rejected. if uri.count('://') != 1: reason = _("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") LOG.debug(_("Invalid store URI: %(reason)s"), {'reason': reason}) raise exception.BadStoreUri(message=reason) pieces = urlparse.urlparse(uri) assert pieces.scheme in ('swift', 'swift+http', 'swift+https') self.scheme = pieces.scheme netloc = pieces.netloc path = pieces.path.lstrip('/') if netloc != '': # > Python 2.6.1 if '@' in netloc: creds, netloc = netloc.split('@') else: creds = None else: # Python 2.6.1 compat # see lp659445 and Python issue7904 if '@' in path: creds, path = path.split('@') else: creds = None netloc = path[0:path.find('/')].strip('/') path = path[path.find('/'):].strip('/') if creds: cred_parts = creds.split(':') if len(cred_parts) != 2: reason = (_("Badly formed credentials in Swift URI.")) LOG.debug(reason) raise exception.BadStoreUri() user, key = cred_parts self.user = urlparse.unquote(user) self.key = urlparse.unquote(key) else: self.user = None self.key = None path_parts = path.split('/') try: self.obj = path_parts.pop() self.container = path_parts.pop() if not netloc.startswith('http'): # push hostname back into the remaining to build full authurl path_parts.insert(0, netloc) self.auth_or_store_url = '/'.join(path_parts) except IndexError: reason = _("Badly formed Swift URI.") LOG.debug(reason) raise exception.BadStoreUri() @property def swift_url(self): """ Creates a fully-qualified auth url that the Swift client library can use. The scheme for the auth_url is determined using the scheme included in the `location` field. HTTPS is assumed, unless 'swift+http' is specified. """ if self.auth_or_store_url.startswith('http'): return self.auth_or_store_url else: if self.scheme in ('swift+https', 'swift'): auth_scheme = 'https://' else: auth_scheme = 'http://' return ''.join([auth_scheme, self.auth_or_store_url]) def Store(context=None, loc=None): if (CONF.swift_store_multi_tenant and (loc is None or loc.store_location.user is None)): return MultiTenantStore(context, loc) return SingleTenantStore(context, loc) class BaseStore(glance.store.base.Store): CHUNKSIZE = 65536 def get_schemes(self): return ('swift+https', 'swift', 'swift+http') def configure(self): _obj_size = self._option_get('swift_store_large_object_size') self.large_object_size = _obj_size * ONE_MB _chunk_size = self._option_get('swift_store_large_object_chunk_size') self.large_object_chunk_size = _chunk_size * ONE_MB self.admin_tenants = CONF.swift_store_admin_tenants self.region = CONF.swift_store_region self.service_type = CONF.swift_store_service_type self.endpoint_type = CONF.swift_store_endpoint_type self.snet = CONF.swift_enable_snet self.insecure = CONF.swift_store_auth_insecure self.ssl_compression = CONF.swift_store_ssl_compression def _get_object(self, location, connection=None, start=None): if not connection: connection = self.get_connection(location) headers = {} if start is not None: bytes_range = 'bytes=%d-' % start headers = {'Range': bytes_range} try: resp_headers, resp_body = connection.get_object( container=location.container, obj=location.obj, resp_chunk_size=self.CHUNKSIZE, headers=headers) except swiftclient.ClientException as e: if e.http_status == httplib.NOT_FOUND: msg = _("Swift could not find object %s.") % location.obj LOG.warn(msg) raise exception.NotFound(msg) else: raise return (resp_headers, resp_body) def get(self, location, connection=None): location = location.store_location (resp_headers, resp_body) = self._get_object(location, connection) class ResponseIndexable(glance.store.Indexable): def another(self): try: return self.wrapped.next() except StopIteration: return '' length = int(resp_headers.get('content-length', 0)) if CONF.swift_store_retry_get_count > 0: resp_body = swift_retry_iter(resp_body, length, self, location) return (ResponseIndexable(resp_body, length), length) def get_size(self, location, connection=None): location = location.store_location if not connection: connection = self.get_connection(location) try: resp_headers = connection.head_object( container=location.container, obj=location.obj) return int(resp_headers.get('content-length', 0)) except Exception: return 0 def _option_get(self, param): result = getattr(CONF, param) if not result: reason = (_("Could not find %(param)s in configuration " "options.") % {'param': param}) LOG.error(reason) raise exception.BadStoreConfiguration(store_name="swift", reason=reason) return result def _delete_stale_chunks(self, connection, container, chunk_list): for chunk in chunk_list: LOG.debug(_("Deleting chunk %s") % chunk) try: connection.delete_object(container, chunk) except Exception: msg = _("Failed to delete orphaned chunk " "%(container)s/%(chunk)s") LOG.exception(msg % {'container': container, 'chunk': chunk}) def add(self, image_id, image_file, image_size, connection=None): location = self.create_location(image_id) if not connection: connection = self.get_connection(location) self._create_container_if_missing(location.container, connection) LOG.debug(_("Adding image object '%(obj_name)s' " "to Swift") % dict(obj_name=location.obj)) try: if image_size > 0 and image_size < self.large_object_size: # Image size is known, and is less than large_object_size. # Send to Swift with regular PUT. obj_etag = connection.put_object(location.container, location.obj, image_file, content_length=image_size) else: # Write the image into Swift in chunks. chunk_id = 1 if image_size > 0: total_chunks = str(int( math.ceil(float(image_size) / float(self.large_object_chunk_size)))) else: # image_size == 0 is when we don't know the size # of the image. This can occur with older clients # that don't inspect the payload size. LOG.debug(_("Cannot determine image size. Adding as a " "segmented object to Swift.")) total_chunks = '?' checksum = hashlib.md5() written_chunks = [] combined_chunks_size = 0 while True: chunk_size = self.large_object_chunk_size if image_size == 0: content_length = None else: left = image_size - combined_chunks_size if left == 0: break if chunk_size > left: chunk_size = left content_length = chunk_size chunk_name = "%s-%05d" % (location.obj, chunk_id) reader = ChunkReader(image_file, checksum, chunk_size) try: chunk_etag = connection.put_object( location.container, chunk_name, reader, content_length=content_length) written_chunks.append(chunk_name) except Exception: # Delete orphaned segments from swift backend with excutils.save_and_reraise_exception(): LOG.exception(_("Error during chunked upload to " "backend, deleting stale chunks")) self._delete_stale_chunks(connection, location.container, written_chunks) bytes_read = reader.bytes_read msg = (_("Wrote chunk %(chunk_name)s (%(chunk_id)d/" "%(total_chunks)s) of length %(bytes_read)d " "to Swift returning MD5 of content: " "%(chunk_etag)s") % {'chunk_name': chunk_name, 'chunk_id': chunk_id, 'total_chunks': total_chunks, 'bytes_read': bytes_read, 'chunk_etag': chunk_etag}) LOG.debug(msg) if bytes_read == 0: # Delete the last chunk, because it's of zero size. # This will happen if size == 0. LOG.debug(_("Deleting final zero-length chunk")) connection.delete_object(location.container, chunk_name) break chunk_id += 1 combined_chunks_size += bytes_read # In the case we have been given an unknown image size, # set the size to the total size of the combined chunks. if image_size == 0: image_size = combined_chunks_size # Now we write the object manifest and return the # manifest's etag... manifest = "%s/%s-" % (location.container, location.obj) headers = {'ETag': hashlib.md5("").hexdigest(), 'X-Object-Manifest': manifest} # The ETag returned for the manifest is actually the # MD5 hash of the concatenated checksums of the strings # 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 connection.put_object(location.container, location.obj, None, headers=headers) obj_etag = checksum.hexdigest() # NOTE: We return the user and key here! Have to because # location is used by the API server to return the actual # image data. We *really* should consider NOT returning # the location attribute from GET /images/ and # GET /images/details return (location.get_uri(), image_size, obj_etag, {}) except swiftclient.ClientException as e: if e.http_status == httplib.CONFLICT: raise exception.Duplicate(_("Swift already has an image at " "this location")) msg = (_("Failed to add object to Swift.\n" "Got error from Swift: %(e)s") % {'e': e}) LOG.error(msg) raise glance.store.BackendException(msg) def delete(self, location, connection=None): location = location.store_location if not connection: connection = self.get_connection(location) try: # We request the manifest for the object. If one exists, # that means the object was uploaded in chunks/segments, # and we need to delete all the chunks as well as the # manifest. manifest = None try: headers = connection.head_object( location.container, location.obj) manifest = headers.get('x-object-manifest') except swiftclient.ClientException as e: if e.http_status != httplib.NOT_FOUND: raise if manifest: # Delete all the chunks before the object manifest itself obj_container, obj_prefix = manifest.split('/', 1) segments = connection.get_container( obj_container, prefix=obj_prefix)[1] for segment in segments: # TODO(jaypipes): This would be an easy area to parallelize # since we're simply sending off parallelizable requests # to Swift to delete stuff. It's not like we're going to # be hogging up network or file I/O here... connection.delete_object(obj_container, segment['name']) # Delete object (or, in segmented case, the manifest) connection.delete_object(location.container, location.obj) except swiftclient.ClientException as e: if e.http_status == httplib.NOT_FOUND: msg = _("Swift could not find image at URI.") raise exception.NotFound(msg) else: raise def _create_container_if_missing(self, container, connection): """ Creates a missing container in Swift if the ``swift_store_create_container_on_put`` option is set. :param container: Name of container to create :param connection: Connection to swift service """ try: connection.head_container(container) except swiftclient.ClientException as e: if e.http_status == httplib.NOT_FOUND: if CONF.swift_store_create_container_on_put: try: connection.put_container(container) except swiftclient.ClientException as e: msg = (_("Failed to add container to Swift.\n" "Got error from Swift: %(e)s") % {'e': e}) raise glance.store.BackendException(msg) else: msg = (_("The container %(container)s does not exist in " "Swift. Please set the " "swift_store_create_container_on_put option" "to add container to Swift automatically.") % {'container': container}) raise glance.store.BackendException(msg) else: raise def get_connection(self): raise NotImplemented() def create_location(self): raise NotImplemented() class SingleTenantStore(BaseStore): EXAMPLE_URL = "swift://:@//" def configure(self): super(SingleTenantStore, self).configure() self.auth_version = self._option_get('swift_store_auth_version') def configure_add(self): self.auth_address = self._option_get('swift_store_auth_address') if self.auth_address.startswith('http://'): self.scheme = 'swift+http' else: self.scheme = 'swift+https' self.container = CONF.swift_store_container self.user = self._option_get('swift_store_user') self.key = self._option_get('swift_store_key') def create_location(self, image_id): specs = {'scheme': self.scheme, 'container': self.container, 'obj': str(image_id), 'auth_or_store_url': self.auth_address, 'user': self.user, 'key': self.key} return StoreLocation(specs) def get_connection(self, location): if not location.user: reason = (_("Location is missing user:password information.")) LOG.debug(reason) raise exception.BadStoreUri(message=reason) auth_url = location.swift_url if not auth_url.endswith('/'): auth_url += '/' if self.auth_version == '2': try: tenant_name, user = location.user.split(':') except ValueError: reason = (_("Badly formed tenant:user '%(user)s' in " "Swift URI") % {'user': location.user}) LOG.debug(reason) raise exception.BadStoreUri() else: tenant_name = None user = location.user os_options = {} if self.region: os_options['region_name'] = self.region os_options['endpoint_type'] = self.endpoint_type os_options['service_type'] = self.service_type return swiftclient.Connection( auth_url, user, location.key, insecure=self.insecure, tenant_name=tenant_name, snet=self.snet, auth_version=self.auth_version, os_options=os_options, ssl_compression=self.ssl_compression) class MultiTenantStore(BaseStore): EXAMPLE_URL = "swift:////" def configure_add(self): self.container = CONF.swift_store_container if self.context is None: reason = _("Multi-tenant Swift storage requires a context.") raise exception.BadStoreConfiguration(store_name="swift", reason=reason) if self.context.service_catalog is None: reason = _("Multi-tenant Swift storage requires " "a service catalog.") raise exception.BadStoreConfiguration(store_name="swift", reason=reason) self.storage_url = auth.get_endpoint( self.context.service_catalog, service_type=self.service_type, endpoint_region=self.region, endpoint_type=self.endpoint_type) if self.storage_url.startswith('http://'): self.scheme = 'swift+http' else: self.scheme = 'swift+https' def delete(self, location, connection=None): if not connection: connection = self.get_connection(location.store_location) super(MultiTenantStore, self).delete(location, connection) connection.delete_container(location.store_location.container) def set_acls(self, location, public=False, read_tenants=None, write_tenants=None, connection=None): location = location.store_location if not connection: connection = self.get_connection(location) if read_tenants is None: read_tenants = [] if write_tenants is None: write_tenants = [] headers = {} if public: headers['X-Container-Read'] = ".r:*,.rlistings" elif read_tenants: headers['X-Container-Read'] = ','.join('%s:*' % i for i in read_tenants) else: headers['X-Container-Read'] = '' write_tenants.extend(self.admin_tenants) if write_tenants: headers['X-Container-Write'] = ','.join('%s:*' % i for i in write_tenants) else: headers['X-Container-Write'] = '' try: connection.post_container(location.container, headers=headers) except swiftclient.ClientException as e: if e.http_status == httplib.NOT_FOUND: msg = _("Swift could not find image at URI.") raise exception.NotFound(msg) else: raise def create_location(self, image_id): specs = {'scheme': self.scheme, 'container': self.container + '_' + str(image_id), 'obj': str(image_id), 'auth_or_store_url': self.storage_url} return StoreLocation(specs) def get_connection(self, location): return swiftclient.Connection( None, self.context.user, None, preauthurl=location.swift_url, preauthtoken=self.context.auth_tok, tenant_name=self.context.tenant, auth_version='2', snet=self.snet, insecure=self.insecure, ssl_compression=self.ssl_compression) class ChunkReader(object): def __init__(self, fd, checksum, total): self.fd = fd self.checksum = checksum self.total = total self.bytes_read = 0 def read(self, i): left = self.total - self.bytes_read if i > left: i = left result = self.fd.read(i) self.bytes_read += len(result) self.checksum.update(result) return result glance-2014.1/glance/store/rbd.py0000664000175400017540000004012612323736230017702 0ustar jenkinsjenkins00000000000000# Copyright 2010-2011 Josh Durgin # 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. """Storage backend for RBD (RADOS (Reliable Autonomic Distributed Object Store) Block Device)""" from __future__ import absolute_import from __future__ import with_statement import hashlib import math from oslo.config import cfg import six.moves.urllib.parse as urlparse from glance.common import exception from glance.common import utils import glance.openstack.common.log as logging from glance.openstack.common import units import glance.store.base import glance.store.location try: import rados import rbd except ImportError: rados = None rbd = None DEFAULT_POOL = 'images' DEFAULT_CONFFILE = '/etc/ceph/ceph.conf' DEFAULT_USER = None # let librados decide based on the Ceph conf file DEFAULT_CHUNKSIZE = 8 # in MiB DEFAULT_SNAPNAME = 'snap' LOG = logging.getLogger(__name__) rbd_opts = [ cfg.IntOpt('rbd_store_chunk_size', default=DEFAULT_CHUNKSIZE, help=_('RADOS images will be chunked into objects of this size ' '(in megabytes). For best performance, this should be ' 'a power of two.')), cfg.StrOpt('rbd_store_pool', default=DEFAULT_POOL, help=_('RADOS pool in which images are stored.')), cfg.StrOpt('rbd_store_user', default=DEFAULT_USER, help=_('RADOS user to authenticate as (only applicable if ' 'using Cephx. If , a default will be chosen based ' 'on the client. section in rbd_store_ceph_conf).')), cfg.StrOpt('rbd_store_ceph_conf', default=DEFAULT_CONFFILE, help=_('Ceph configuration file path. ' 'If , librados will locate the default config. ' 'If using cephx authentication, this file should ' 'include a reference to the right keyring ' 'in a client. section.')), ] CONF = cfg.CONF CONF.register_opts(rbd_opts) class StoreLocation(glance.store.location.StoreLocation): """ Class describing a RBD URI. This is of the form: rbd://image or rbd://fsid/pool/image/snapshot """ def process_specs(self): # convert to ascii since librbd doesn't handle unicode for key, value in self.specs.iteritems(): self.specs[key] = str(value) self.fsid = self.specs.get('fsid') self.pool = self.specs.get('pool') self.image = self.specs.get('image') self.snapshot = self.specs.get('snapshot') def get_uri(self): if self.fsid and self.pool and self.snapshot: # ensure nothing contains / or any other url-unsafe character safe_fsid = urlparse.quote(self.fsid, '') safe_pool = urlparse.quote(self.pool, '') safe_image = urlparse.quote(self.image, '') safe_snapshot = urlparse.quote(self.snapshot, '') return "rbd://%s/%s/%s/%s" % (safe_fsid, safe_pool, safe_image, safe_snapshot) else: return "rbd://%s" % self.image def parse_uri(self, uri): prefix = 'rbd://' if not uri.startswith(prefix): reason = _('URI must start with rbd://') msg = (_("Invalid URI: %(uri)s: %(reason)s") % {'uri': uri, 'reason': reason}) LOG.debug(msg) raise exception.BadStoreUri(message=reason) # convert to ascii since librbd doesn't handle unicode try: ascii_uri = str(uri) except UnicodeError: reason = _('URI contains non-ascii characters') msg = (_("Invalid URI: %(uri)s: %(reason)s") % {'uri': uri, 'reason': reason}) LOG.debug(msg) raise exception.BadStoreUri(message=reason) pieces = ascii_uri[len(prefix):].split('/') if len(pieces) == 1: self.fsid, self.pool, self.image, self.snapshot = \ (None, None, pieces[0], None) elif len(pieces) == 4: self.fsid, self.pool, self.image, self.snapshot = \ map(urlparse.unquote, pieces) else: reason = _('URI must have exactly 1 or 4 components') msg = (_("Invalid URI: %(uri)s: %(reason)s") % {'uri': uri, 'reason': reason}) LOG.debug(msg) raise exception.BadStoreUri(message=reason) if any(map(lambda p: p == '', pieces)): reason = _('URI cannot contain empty components') msg = (_("Invalid URI: %(uri)s: %(reason)s") % {'uri': uri, 'reason': reason}) LOG.debug(msg) raise exception.BadStoreUri(message=reason) class ImageIterator(object): """ Reads data from an RBD image, one chunk at a time. """ def __init__(self, name, store): self.name = name self.pool = store.pool self.user = store.user self.conf_file = store.conf_file self.chunk_size = store.chunk_size def __iter__(self): try: with rados.Rados(conffile=self.conf_file, rados_id=self.user) as conn: with conn.open_ioctx(self.pool) as ioctx: with rbd.Image(ioctx, self.name) as image: img_info = image.stat() size = img_info['size'] bytes_left = size while bytes_left > 0: length = min(self.chunk_size, bytes_left) data = image.read(size - bytes_left, length) bytes_left -= len(data) yield data raise StopIteration() except rbd.ImageNotFound: raise exception.NotFound( _('RBD image %s does not exist') % self.name) class Store(glance.store.base.Store): """An implementation of the RBD backend adapter.""" EXAMPLE_URL = "rbd://///" def get_schemes(self): return ('rbd',) def configure_add(self): """ Configure the Store to use the stored configuration options Any store that needs special configuration should implement this method. If the store was not able to successfully configure itself, it should raise `exception.BadStoreConfiguration` """ try: self.chunk_size = CONF.rbd_store_chunk_size * units.Mi # these must not be unicode since they will be passed to a # non-unicode-aware C library self.pool = str(CONF.rbd_store_pool) self.user = str(CONF.rbd_store_user) self.conf_file = str(CONF.rbd_store_ceph_conf) except cfg.ConfigFileValueError as e: reason = _("Error in store configuration: %s") % e LOG.error(reason) raise exception.BadStoreConfiguration(store_name='rbd', reason=reason) def get(self, location): """ Takes a `glance.store.location.Location` object that indicates where to find the image file, and returns a tuple of generator (for reading the image file) and image_size :param location `glance.store.location.Location` object, supplied from glance.store.location.get_location_from_uri() :raises `glance.exception.NotFound` if image does not exist """ loc = location.store_location return (ImageIterator(loc.image, self), self.get_size(location)) def get_size(self, location): """ Takes a `glance.store.location.Location` object that indicates where to find the image file, and returns the size :param location `glance.store.location.Location` object, supplied from glance.store.location.get_location_from_uri() :raises `glance.exception.NotFound` if image does not exist """ loc = location.store_location with rados.Rados(conffile=self.conf_file, rados_id=self.user) as conn: with conn.open_ioctx(self.pool) as ioctx: try: with rbd.Image(ioctx, loc.image, snapshot=loc.snapshot) as image: img_info = image.stat() return img_info['size'] except rbd.ImageNotFound: msg = _('RBD image %s does not exist') % loc.get_uri() LOG.debug(msg) raise exception.NotFound(msg) def _create_image(self, fsid, ioctx, image_name, size, order): """ Create an rbd image. If librbd supports it, make it a cloneable snapshot, so that copy-on-write volumes can be created from it. :param image_name Image's name :retval `glance.store.rbd.StoreLocation` object """ librbd = rbd.RBD() if hasattr(rbd, 'RBD_FEATURE_LAYERING'): librbd.create(ioctx, image_name, size, order, old_format=False, features=rbd.RBD_FEATURE_LAYERING) return StoreLocation({ 'fsid': fsid, 'pool': self.pool, 'image': image_name, 'snapshot': DEFAULT_SNAPNAME, }) else: librbd.create(ioctx, image_name, size, order, old_format=True) return StoreLocation({'image': image_name}) def _delete_image(self, image_name, snapshot_name=None): """ Delete RBD image and snapshot. :param image_name Image's name :param snapshot_name Image snapshot's name :raises NotFound if image does not exist; InUseByStore if image is in use or snapshot unprotect failed """ with rados.Rados(conffile=self.conf_file, rados_id=self.user) as conn: with conn.open_ioctx(self.pool) as ioctx: try: # First remove snapshot. if snapshot_name is not None: with rbd.Image(ioctx, image_name) as image: try: image.unprotect_snap(snapshot_name) except rbd.ImageBusy: log_msg = _("snapshot %(image)s@%(snap)s " "could not be unprotected because " "it is in use") LOG.debug(log_msg % {'image': image_name, 'snap': snapshot_name}) raise exception.InUseByStore() image.remove_snap(snapshot_name) # Then delete image. rbd.RBD().remove(ioctx, image_name) except rbd.ImageNotFound: raise exception.NotFound( _("RBD image %s does not exist") % image_name) except rbd.ImageBusy: log_msg = _("image %s could not be removed " "because it is in use") LOG.debug(log_msg % image_name) raise exception.InUseByStore() def add(self, image_id, image_file, image_size): """ Stores an image file with supplied identifier to the backend storage system and returns a tuple containing information about the stored image. :param image_id: The opaque image identifier :param image_file: The image data to write, as a file-like object :param image_size: The size of the image data to write, in bytes :retval tuple of URL in backing store, bytes written, checksum and a dictionary with storage system specific information :raises `glance.common.exception.Duplicate` if the image already existed """ checksum = hashlib.md5() image_name = str(image_id) with rados.Rados(conffile=self.conf_file, rados_id=self.user) as conn: fsid = None if hasattr(conn, 'get_fsid'): fsid = conn.get_fsid() with conn.open_ioctx(self.pool) as ioctx: order = int(math.log(self.chunk_size, 2)) LOG.debug('creating image %s with order %d and size %d', image_name, order, image_size) if image_size == 0: LOG.warning(_("since image size is zero we will be doing " "resize-before-write for each chunk which " "will be considerably slower than normal")) try: loc = self._create_image(fsid, ioctx, image_name, image_size, order) except rbd.ImageExists: raise exception.Duplicate( _('RBD image %s already exists') % image_id) try: with rbd.Image(ioctx, image_name) as image: bytes_written = 0 offset = 0 chunks = utils.chunkreadable(image_file, self.chunk_size) for chunk in chunks: # If the image size provided is zero we need to do # a resize for the amount we are writing. This will # be slower so setting a higher chunk size may # speed things up a bit. if image_size == 0: chunk_length = len(chunk) length = offset + chunk_length bytes_written += chunk_length LOG.debug(_("resizing image to %s KiB") % (length / units.Ki)) image.resize(length) LOG.debug(_("writing chunk at offset %s") % (offset)) offset += image.write(chunk, offset) checksum.update(chunk) if loc.snapshot: image.create_snap(loc.snapshot) image.protect_snap(loc.snapshot) except Exception as exc: # Delete image if one was created try: self._delete_image(loc.image, loc.snapshot) except exception.NotFound: pass raise exc # Make sure we send back the image size whether provided or inferred. if image_size == 0: image_size = bytes_written return (loc.get_uri(), image_size, checksum.hexdigest(), {}) def delete(self, location): """ Takes a `glance.store.location.Location` object that indicates where to find the image file to delete. :location `glance.store.location.Location` object, supplied from glance.store.location.get_location_from_uri() :raises NotFound if image does not exist; InUseByStore if image is in use or snapshot unprotect failed """ loc = location.store_location self._delete_image(loc.image, loc.snapshot) glance-2014.1/glance/store/cinder.py0000664000175400017540000001536712323736226020415 0ustar jenkinsjenkins00000000000000# 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. """Storage backend for Cinder""" from cinderclient import exceptions as cinder_exception from cinderclient import service_catalog from cinderclient.v2 import client as cinderclient from oslo.config import cfg from glance.common import exception from glance.common import utils import glance.openstack.common.log as logging from glance.openstack.common import units import glance.store.base import glance.store.location LOG = logging.getLogger(__name__) cinder_opts = [ cfg.StrOpt('cinder_catalog_info', default='volume:cinder:publicURL', help='Info to match when looking for cinder in the service ' 'catalog. Format is: separated values of the form: ' '::.'), cfg.StrOpt('cinder_endpoint_template', default=None, help='Override service catalog lookup with template for cinder ' 'endpoint e.g. http://localhost:8776/v1/%(project_id)s.'), cfg.StrOpt('os_region_name', default=None, help='Region name of this node.'), cfg.StrOpt('cinder_ca_certificates_file', default=None, help='Location of CA certicates file to use for cinder client ' 'requests.'), cfg.IntOpt('cinder_http_retries', default=3, help='Number of cinderclient retries on failed http calls.'), cfg.BoolOpt('cinder_api_insecure', default=False, help='Allow to perform insecure SSL requests to cinder.'), ] CONF = cfg.CONF CONF.register_opts(cinder_opts) def get_cinderclient(context): if CONF.cinder_endpoint_template: url = CONF.cinder_endpoint_template % context.to_dict() else: info = CONF.cinder_catalog_info service_type, service_name, endpoint_type = info.split(':') # extract the region if set in configuration if CONF.os_region_name: attr = 'region' filter_value = CONF.os_region_name else: attr = None filter_value = None # FIXME: the cinderclient ServiceCatalog object is mis-named. # It actually contains the entire access blob. # Only needed parts of the service catalog are passed in, see # nova/context.py. compat_catalog = { 'access': {'serviceCatalog': context.service_catalog or []}} sc = service_catalog.ServiceCatalog(compat_catalog) url = sc.url_for(attr=attr, filter_value=filter_value, service_type=service_type, service_name=service_name, endpoint_type=endpoint_type) LOG.debug(_('Cinderclient connection created using URL: %s') % url) c = cinderclient.Client(context.user, context.auth_tok, project_id=context.tenant, auth_url=url, insecure=CONF.cinder_api_insecure, retries=CONF.cinder_http_retries, cacert=CONF.cinder_ca_certificates_file) # noauth extracts user_id:project_id from auth_token c.client.auth_token = context.auth_tok or '%s:%s' % (context.user, context.tenant) c.client.management_url = url return c class StoreLocation(glance.store.location.StoreLocation): """Class describing a Cinder URI""" def process_specs(self): self.scheme = self.specs.get('scheme', 'cinder') self.volume_id = self.specs.get('volume_id') def get_uri(self): return "cinder://%s" % self.volume_id def parse_uri(self, uri): if not uri.startswith('cinder://'): reason = _("URI must start with cinder://") LOG.error(reason) raise exception.BadStoreUri(uri, reason) self.scheme = 'cinder' self.volume_id = uri[9:] if not utils.is_uuid_like(self.volume_id): reason = _("URI contains invalid volume ID: %s") % self.volume_id LOG.error(reason) raise exception.BadStoreUri(uri, reason) class Store(glance.store.base.Store): """Cinder backend store adapter.""" EXAMPLE_URL = "cinder://volume-id" def get_schemes(self): return ('cinder',) def configure_add(self): """ Configure the Store to use the stored configuration options Any store that needs special configuration should implement this method. If the store was not able to successfully configure itself, it should raise `exception.BadStoreConfiguration` """ if self.context is None: reason = _("Cinder storage requires a context.") raise exception.BadStoreConfiguration(store_name="cinder", reason=reason) if self.context.service_catalog is None: reason = _("Cinder storage requires a service catalog.") raise exception.BadStoreConfiguration(store_name="cinder", reason=reason) def get_size(self, location): """ Takes a `glance.store.location.Location` object that indicates where to find the image file and returns the image size :param location `glance.store.location.Location` object, supplied from glance.store.location.get_location_from_uri() :raises `glance.exception.NotFound` if image does not exist :rtype int """ loc = location.store_location try: volume = get_cinderclient(self.context).volumes.get(loc.volume_id) # GB unit convert to byte return volume.size * units.Gi except cinder_exception.NotFound as e: reason = _("Failed to get image size due to " "volume can not be found: %s") % self.volume_id LOG.error(reason) raise exception.NotFound(reason) except Exception as e: LOG.exception(_("Failed to get image size due to " "internal error: %s") % e) return 0 glance-2014.1/glance/store/s3.py0000664000175400017540000005035312323736226017470 0ustar jenkinsjenkins00000000000000# Copyright 2010 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """Storage backend for S3 or Storage Servers that follow the S3 Protocol""" import hashlib import httplib import re import tempfile from oslo.config import cfg import six.moves.urllib.parse as urlparse from glance.common import exception from glance.common import utils import glance.openstack.common.log as logging import glance.store import glance.store.base import glance.store.location LOG = logging.getLogger(__name__) s3_opts = [ cfg.StrOpt('s3_store_host', help=_('The host where the S3 server is listening.')), cfg.StrOpt('s3_store_access_key', secret=True, help=_('The S3 query token access key.')), cfg.StrOpt('s3_store_secret_key', secret=True, help=_('The S3 query token secret key.')), cfg.StrOpt('s3_store_bucket', help=_('The S3 bucket to be used to store the Glance data.')), cfg.StrOpt('s3_store_object_buffer_dir', help=_('The local directory where uploads will be staged ' 'before they are transferred into S3.')), cfg.BoolOpt('s3_store_create_bucket_on_put', default=False, help=_('A boolean to determine if the S3 bucket should be ' 'created on upload if it does not exist or if ' 'an error should be returned to the user.')), cfg.StrOpt('s3_store_bucket_url_format', default='subdomain', help=_('The S3 calling format used to determine the bucket. ' 'Either subdomain or path can be used.')), ] CONF = cfg.CONF CONF.register_opts(s3_opts) class StoreLocation(glance.store.location.StoreLocation): """ Class describing an S3 URI. An S3 URI can look like any of the following: s3://accesskey:secretkey@s3.amazonaws.com/bucket/key-id s3+http://accesskey:secretkey@s3.amazonaws.com/bucket/key-id s3+https://accesskey:secretkey@s3.amazonaws.com/bucket/key-id The s3+https:// URIs indicate there is an HTTPS s3service URL """ def process_specs(self): self.scheme = self.specs.get('scheme', 's3') self.accesskey = self.specs.get('accesskey') self.secretkey = self.specs.get('secretkey') s3_host = self.specs.get('s3serviceurl') self.bucket = self.specs.get('bucket') self.key = self.specs.get('key') if s3_host.startswith('https://'): self.scheme = 's3+https' s3_host = s3_host[8:].strip('/') elif s3_host.startswith('http://'): s3_host = s3_host[7:].strip('/') self.s3serviceurl = s3_host.strip('/') def _get_credstring(self): if self.accesskey: return '%s:%s@' % (self.accesskey, self.secretkey) return '' def get_uri(self): return "%s://%s%s/%s/%s" % ( self.scheme, self._get_credstring(), self.s3serviceurl, self.bucket, self.key) def parse_uri(self, uri): """ Parse URLs. This method fixes an issue where credentials specified in the URL are interpreted differently in Python 2.6.1+ than prior versions of Python. Note that an Amazon AWS secret key can contain the forward slash, which is entirely retarded, and breaks urlparse miserably. This function works around that issue. """ # Make sure that URIs that contain multiple schemes, such as: # s3://accesskey:secretkey@https://s3.amazonaws.com/bucket/key-id # are immediately rejected. if uri.count('://') != 1: reason = _("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") LOG.debug(_("Invalid store uri: %s") % reason) raise exception.BadStoreUri(message=reason) pieces = urlparse.urlparse(uri) assert pieces.scheme in ('s3', 's3+http', 's3+https') self.scheme = pieces.scheme path = pieces.path.strip('/') netloc = pieces.netloc.strip('/') entire_path = (netloc + '/' + path).strip('/') if '@' in uri: creds, path = entire_path.split('@') cred_parts = creds.split(':') try: access_key = cred_parts[0] secret_key = cred_parts[1] # NOTE(jaypipes): Need to encode to UTF-8 here because of a # bug in the HMAC library that boto uses. # See: http://bugs.python.org/issue5285 # See: http://trac.edgewall.org/ticket/8083 access_key = access_key.encode('utf-8') secret_key = secret_key.encode('utf-8') self.accesskey = access_key self.secretkey = secret_key except IndexError: reason = _("Badly formed S3 credentials %s") % creds LOG.debug(reason) raise exception.BadStoreUri() else: self.accesskey = None path = entire_path try: path_parts = path.split('/') self.key = path_parts.pop() self.bucket = path_parts.pop() if path_parts: self.s3serviceurl = '/'.join(path_parts).strip('/') else: reason = _("Badly formed S3 URI. Missing s3 service URL.") raise exception.BadStoreUri() except IndexError: reason = _("Badly formed S3 URI: %s") % uri LOG.debug(reason) raise exception.BadStoreUri() class ChunkedFile(object): """ We send this back to the Glance API server as something that can iterate over a ``boto.s3.key.Key`` """ CHUNKSIZE = 65536 def __init__(self, fp): self.fp = fp def __iter__(self): """Return an iterator over the image file""" try: if self.fp: while True: chunk = self.fp.read(ChunkedFile.CHUNKSIZE) if chunk: yield chunk else: break finally: self.close() def getvalue(self): """Return entire string value... used in testing.""" data = "" self.len = 0 for chunk in self: read_bytes = len(chunk) data = data + chunk self.len = self.len + read_bytes return data def close(self): """Close the internal file pointer.""" if self.fp: self.fp.close() self.fp = None class Store(glance.store.base.Store): """An implementation of the s3 adapter.""" EXAMPLE_URL = "s3://:@//" def get_schemes(self): return ('s3', 's3+http', 's3+https') def configure_add(self): """ Configure the Store to use the stored configuration options Any store that needs special configuration should implement this method. If the store was not able to successfully configure itself, it should raise `exception.BadStoreConfiguration` """ self.s3_host = self._option_get('s3_store_host') access_key = self._option_get('s3_store_access_key') secret_key = self._option_get('s3_store_secret_key') # NOTE(jaypipes): Need to encode to UTF-8 here because of a # bug in the HMAC library that boto uses. # See: http://bugs.python.org/issue5285 # See: http://trac.edgewall.org/ticket/8083 self.access_key = access_key.encode('utf-8') self.secret_key = secret_key.encode('utf-8') self.bucket = self._option_get('s3_store_bucket') self.scheme = 's3' if self.s3_host.startswith('https://'): self.scheme = 's3+https' self.full_s3_host = self.s3_host elif self.s3_host.startswith('http://'): self.full_s3_host = self.s3_host else: # Defaults http self.full_s3_host = 'http://' + self.s3_host self.s3_store_object_buffer_dir = CONF.s3_store_object_buffer_dir def _option_get(self, param): result = getattr(CONF, param) if not result: reason = (_("Could not find %(param)s in configuration " "options.") % {'param': param}) LOG.debug(reason) raise exception.BadStoreConfiguration(store_name="s3", reason=reason) return result def get(self, location): """ Takes a `glance.store.location.Location` object that indicates where to find the image file, and returns a tuple of generator (for reading the image file) and image_size :param location `glance.store.location.Location` object, supplied from glance.store.location.get_location_from_uri() :raises `glance.exception.NotFound` if image does not exist """ key = self._retrieve_key(location) key.BufferSize = self.CHUNKSIZE class ChunkedIndexable(glance.store.Indexable): def another(self): return (self.wrapped.fp.read(ChunkedFile.CHUNKSIZE) if self.wrapped.fp else None) return (ChunkedIndexable(ChunkedFile(key), key.size), key.size) def get_size(self, location): """ Takes a `glance.store.location.Location` object that indicates where to find the image file, and returns the image_size (or 0 if unavailable) :param location `glance.store.location.Location` object, supplied from glance.store.location.get_location_from_uri() """ try: key = self._retrieve_key(location) return key.size except Exception: return 0 def _retrieve_key(self, location): loc = location.store_location from boto.s3.connection import S3Connection s3_conn = S3Connection(loc.accesskey, loc.secretkey, host=loc.s3serviceurl, is_secure=(loc.scheme == 's3+https'), calling_format=get_calling_format()) bucket_obj = get_bucket(s3_conn, loc.bucket) key = get_key(bucket_obj, loc.key) msg = _("Retrieved image object from S3 using (s3_host=%(s3_host)s, " "access_key=%(accesskey)s, bucket=%(bucket)s, " "key=%(obj_name)s)") % ({'s3_host': loc.s3serviceurl, 'accesskey': loc.accesskey, 'bucket': loc.bucket, 'obj_name': loc.key}) LOG.debug(msg) return key def add(self, image_id, image_file, image_size): """ Stores an image file with supplied identifier to the backend storage system and returns a tuple containing information about the stored image. :param image_id: The opaque image identifier :param image_file: The image data to write, as a file-like object :param image_size: The size of the image data to write, in bytes :retval tuple of URL in backing store, bytes written, checksum and a dictionary with storage system specific information :raises `glance.common.exception.Duplicate` if the image already existed S3 writes the image data using the scheme: s3://:@// where: = ``s3_store_user`` = ``s3_store_key`` = ``s3_store_host`` = ``s3_store_bucket`` = The id of the image being added """ from boto.s3.connection import S3Connection loc = StoreLocation({'scheme': self.scheme, 'bucket': self.bucket, 'key': image_id, 's3serviceurl': self.full_s3_host, 'accesskey': self.access_key, 'secretkey': self.secret_key}) s3_conn = S3Connection(loc.accesskey, loc.secretkey, host=loc.s3serviceurl, is_secure=(loc.scheme == 's3+https'), calling_format=get_calling_format()) create_bucket_if_missing(self.bucket, s3_conn) bucket_obj = get_bucket(s3_conn, self.bucket) obj_name = str(image_id) def _sanitize(uri): return re.sub('//.*:.*@', '//s3_store_secret_key:s3_store_access_key@', uri) key = bucket_obj.get_key(obj_name) if key and key.exists(): raise exception.Duplicate(_("S3 already has an image at " "location %s") % _sanitize(loc.get_uri())) msg = _("Adding image object to S3 using (s3_host=%(s3_host)s, " "access_key=%(access_key)s, bucket=%(bucket)s, " "key=%(obj_name)s)") % ({'s3_host': self.s3_host, 'access_key': self.access_key, 'bucket': self.bucket, 'obj_name': obj_name}) LOG.debug(msg) key = bucket_obj.new_key(obj_name) # We need to wrap image_file, which is a reference to the # webob.Request.body_file, with a seekable file-like object, # otherwise the call to set_contents_from_file() will die # with an error about Input object has no method 'seek'. We # might want to call webob.Request.make_body_seekable(), but # unfortunately, that method copies the entire image into # memory and results in LP Bug #818292 occurring. So, here # we write temporary file in as memory-efficient manner as # possible and then supply the temporary file to S3. We also # take this opportunity to calculate the image checksum while # writing the tempfile, so we don't need to call key.compute_md5() msg = _("Writing request body file to temporary file " "for %s") % _sanitize(loc.get_uri()) LOG.debug(msg) tmpdir = self.s3_store_object_buffer_dir temp_file = tempfile.NamedTemporaryFile(dir=tmpdir) checksum = hashlib.md5() for chunk in utils.chunkreadable(image_file, self.CHUNKSIZE): checksum.update(chunk) temp_file.write(chunk) temp_file.flush() msg = (_("Uploading temporary file to S3 for %s") % _sanitize(loc.get_uri())) LOG.debug(msg) # OK, now upload the data into the key key.set_contents_from_file(open(temp_file.name, 'r+b'), replace=False) size = key.size checksum_hex = checksum.hexdigest() LOG.debug(_("Wrote %(size)d bytes to S3 key named %(obj_name)s " "with checksum %(checksum_hex)s"), {'size': size, 'obj_name': obj_name, 'checksum_hex': checksum_hex}) return (loc.get_uri(), size, checksum_hex, {}) def delete(self, location): """ Takes a `glance.store.location.Location` object that indicates where to find the image file to delete :location `glance.store.location.Location` object, supplied from glance.store.location.get_location_from_uri() :raises NotFound if image does not exist """ loc = location.store_location from boto.s3.connection import S3Connection s3_conn = S3Connection(loc.accesskey, loc.secretkey, host=loc.s3serviceurl, is_secure=(loc.scheme == 's3+https'), calling_format=get_calling_format()) bucket_obj = get_bucket(s3_conn, loc.bucket) # Close the key when we're through. key = get_key(bucket_obj, loc.key) msg = _("Deleting image object from S3 using (s3_host=%(s3_host)s, " "access_key=%(accesskey)s, bucket=%(bucket)s, " "key=%(obj_name)s)") % ({'s3_host': loc.s3serviceurl, 'accesskey': loc.accesskey, 'bucket': loc.bucket, 'obj_name': loc.key}) LOG.debug(msg) return key.delete() def get_bucket(conn, bucket_id): """ Get a bucket from an s3 connection :param conn: The ``boto.s3.connection.S3Connection`` :param bucket_id: ID of the bucket to fetch :raises ``glance.exception.NotFound`` if bucket is not found. """ bucket = conn.get_bucket(bucket_id) if not bucket: msg = _("Could not find bucket with ID %s") % bucket_id LOG.debug(msg) raise exception.NotFound(msg) return bucket def get_s3_location(s3_host): from boto.s3.connection import Location locations = { 's3.amazonaws.com': Location.DEFAULT, 's3-eu-west-1.amazonaws.com': Location.EU, 's3-us-west-1.amazonaws.com': Location.USWest, 's3-ap-southeast-1.amazonaws.com': Location.APSoutheast, 's3-ap-northeast-1.amazonaws.com': Location.APNortheast, } # strip off scheme and port if present key = re.sub('^(https?://)?(?P[^:]+)(:[0-9]+)?$', '\g', s3_host) return locations.get(key, Location.DEFAULT) def create_bucket_if_missing(bucket, s3_conn): """ Creates a missing bucket in S3 if the ``s3_store_create_bucket_on_put`` option is set. :param bucket: Name of bucket to create :param s3_conn: Connection to S3 """ from boto.exception import S3ResponseError try: s3_conn.get_bucket(bucket) except S3ResponseError as e: if e.status == httplib.NOT_FOUND: if CONF.s3_store_create_bucket_on_put: location = get_s3_location(CONF.s3_store_host) try: s3_conn.create_bucket(bucket, location=location) except S3ResponseError as e: msg = (_("Failed to add bucket to S3.\n" "Got error from S3: %(e)s") % {'e': e}) raise glance.store.BackendException(msg) else: msg = (_("The bucket %(bucket)s does not exist in " "S3. Please set the " "s3_store_create_bucket_on_put option " "to add bucket to S3 automatically.") % {'bucket': bucket}) raise glance.store.BackendException(msg) def get_key(bucket, obj): """ Get a key from a bucket :param bucket: The ``boto.s3.Bucket`` :param obj: Object to get the key for :raises ``glance.exception.NotFound`` if key is not found. """ key = bucket.get_key(obj) if not key or not key.exists(): msg = (_("Could not find key %(obj)s in bucket %(bucket)s") % {'obj': obj, 'bucket': bucket}) LOG.debug(msg) raise exception.NotFound(msg) return key def get_calling_format(bucket_format=None): import boto.s3.connection if bucket_format is None: bucket_format = CONF.s3_store_bucket_url_format if bucket_format.lower() == 'path': return boto.s3.connection.OrdinaryCallingFormat() else: return boto.s3.connection.SubdomainCallingFormat() glance-2014.1/glance/store/base.py0000664000175400017540000001370212323736230020045 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation # Copyright 2012 RedHat 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. """Base class for all storage backends""" from glance.common import exception from glance.openstack.common import importutils import glance.openstack.common.log as logging from glance.openstack.common import strutils from glance.openstack.common import units LOG = logging.getLogger(__name__) def _exception_to_unicode(exc): try: return unicode(exc) except UnicodeError: try: return strutils.safe_decode(str(exc), errors='ignore') except UnicodeError: msg = (_("Caught '%(exception)s' exception.") % {"exception": exc.__class__.__name__}) return strutils.safe_decode(msg, errors='ignore') class Store(object): CHUNKSIZE = 16 * units.Mi # 16M def __init__(self, context=None, location=None): """ Initialize the Store """ self.store_location_class = None self.context = context self.configure() try: self.configure_add() except exception.BadStoreConfiguration as e: self.add = self.add_disabled msg = (_(u"Failed to configure store correctly: %s " "Disabling add method.") % _exception_to_unicode(e)) LOG.warn(msg) def configure(self): """ Configure the Store to use the stored configuration options Any store that needs special configuration should implement this method. """ pass def get_schemes(self): """ Returns a tuple of schemes which this store can handle. """ raise NotImplementedError def get_store_location_class(self): """ Returns the store location class that is used by this store. """ if not self.store_location_class: class_name = "%s.StoreLocation" % (self.__module__) LOG.debug("Late loading location class %s", class_name) self.store_location_class = importutils.import_class(class_name) return self.store_location_class def configure_add(self): """ This is like `configure` except that it's specifically for configuring the store to accept objects. If the store was not able to successfully configure itself, it should raise `exception.BadStoreConfiguration`. """ pass def get(self, location): """ Takes a `glance.store.location.Location` object that indicates where to find the image file, and returns a tuple of generator (for reading the image file) and image_size :param location `glance.store.location.Location` object, supplied from glance.store.location.get_location_from_uri() :raises `glance.exception.NotFound` if image does not exist """ raise NotImplementedError def get_size(self, location): """ Takes a `glance.store.location.Location` object that indicates where to find the image file, and returns the size :param location `glance.store.location.Location` object, supplied from glance.store.location.get_location_from_uri() :raises `glance.exception.NotFound` if image does not exist """ raise NotImplementedError def add_disabled(self, *args, **kwargs): """ Add method that raises an exception because the Store was not able to be configured properly and therefore the add() method would error out. """ raise exception.StoreAddDisabled def add(self, image_id, image_file, image_size): """ Stores an image file with supplied identifier to the backend storage system and returns a tuple containing information about the stored image. :param image_id: The opaque image identifier :param image_file: The image data to write, as a file-like object :param image_size: The size of the image data to write, in bytes :retval tuple of URL in backing store, bytes written, checksum and a dictionary with storage system specific information :raises `glance.common.exception.Duplicate` if the image already existed """ raise NotImplementedError def delete(self, location): """ Takes a `glance.store.location.Location` object that indicates where to find the image file to delete :location `glance.store.location.Location` object, supplied from glance.store.location.get_location_from_uri() :raises `glance.exception.NotFound` if image does not exist """ raise NotImplementedError def set_acls(self, location, public=False, read_tenants=[], write_tenants=[]): """ Sets the read and write access control list for an image in the backend store. :location `glance.store.location.Location` object, supplied from glance.store.location.get_location_from_uri() :public A boolean indicating whether the image should be public. :read_tenants A list of tenant strings which should be granted read access for an image. :write_tenants A list of tenant strings which should be granted write access for an image. """ raise NotImplementedError glance-2014.1/glance/store/vmware_datastore.py0000664000175400017540000004146612323736226022517 0ustar jenkinsjenkins00000000000000# Copyright 2014 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. """Storage backend for VMware Datastore""" import hashlib import httplib import os import netaddr from oslo.config import cfg from oslo.vmware import api import six.moves.urllib.parse as urlparse from glance.common import exception from glance.openstack.common import excutils import glance.openstack.common.log as logging import glance.store import glance.store.base import glance.store.location LOG = logging.getLogger(__name__) MAX_REDIRECTS = 5 DEFAULT_STORE_IMAGE_DIR = '/openstack_glance' DEFAULT_ESX_DATACENTER_PATH = 'ha-datacenter' DS_URL_PREFIX = '/folder' STORE_SCHEME = 'vsphere' # check that datacenter/datastore combination is valid _datastore_info_valid = False vmware_opts = [ cfg.StrOpt('vmware_server_host', help=_('ESX/ESXi or vCenter Server target system. ' 'The server value can be an IP address or a DNS name.')), cfg.StrOpt('vmware_server_username', help=_('Username for authenticating with ' 'VMware ESX/VC server.')), cfg.StrOpt('vmware_server_password', help=_('Password for authenticating with ' 'VMware ESX/VC server.'), secret=True), cfg.StrOpt('vmware_datacenter_path', default=DEFAULT_ESX_DATACENTER_PATH, help=_('Inventory path to a datacenter. ' 'If the vmware_server_host specified is an ESX/ESXi, ' 'the vmware_datacenter_path is optional. If specified, ' 'it should be "ha-datacenter".')), cfg.StrOpt('vmware_datastore_name', help=_('Datastore associated with the datacenter.')), cfg.IntOpt('vmware_api_retry_count', default=10, help=_('Number of times VMware ESX/VC server API must be ' 'retried upon connection related issues.')), cfg.IntOpt('vmware_task_poll_interval', default=5, help=_('The interval used for polling remote tasks ' 'invoked on VMware ESX/VC server.')), cfg.StrOpt('vmware_store_image_dir', default=DEFAULT_STORE_IMAGE_DIR, help=_('The name of the directory where the glance images ' 'will be stored in the VMware datastore.')), cfg.BoolOpt('vmware_api_insecure', default=False, help=_('Allow to perform insecure SSL requests to ESX/VC.')), ] CONF = cfg.CONF CONF.register_opts(vmware_opts) def is_valid_ipv6(address): try: return netaddr.valid_ipv6(address) except Exception: return False def http_response_iterator(conn, response, size): """Return an iterator for a file-like object. :param conn: HTTP(S) Connection :param response: httplib.HTTPResponse object :param size: Chunk size to iterate with """ try: chunk = response.read(size) while chunk: yield chunk chunk = response.read(size) finally: conn.close() class _Reader(object): def __init__(self, data, checksum): self.data = data self.checksum = checksum self._size = 0 def read(self, length): result = self.data.read(length) self._size += len(result) self.checksum.update(result) return result @property def size(self): return self._size class StoreLocation(glance.store.location.StoreLocation): """Class describing an VMware URI. An VMware URI can look like any of the following: vsphere://server_host/folder/file_path?dcPath=dc_path&dsName=ds_name """ def process_specs(self): self.scheme = self.specs.get('scheme', STORE_SCHEME) self.server_host = self.specs.get('server_host') self.path = os.path.join(DS_URL_PREFIX, self.specs.get('image_dir').strip('/'), self.specs.get('image_id')) dc_path = self.specs.get('datacenter_path') if dc_path is not None: param_list = {'dcPath': self.specs.get('datacenter_path'), 'dsName': self.specs.get('datastore_name')} else: param_list = {'dsName': self.specs.get('datastore_name')} self.query = urlparse.urlencode(param_list) def get_uri(self): if is_valid_ipv6(self.server_host): base_url = '%s://[%s]%s' % (self.scheme, self.server_host, self.path) else: base_url = '%s://%s%s' % (self.scheme, self.server_host, self.path) return '%s?%s' % (base_url, self.query) def _is_valid_path(self, path): return path.startswith( os.path.join(DS_URL_PREFIX, CONF.vmware_store_image_dir.strip('/'))) def parse_uri(self, uri): if not uri.startswith('%s://' % STORE_SCHEME): reason = (_("URI %(uri)s must start with %(scheme)s://") % {'uri': uri, 'scheme': STORE_SCHEME}) LOG.error(reason) raise exception.BadStoreUri(reason) (self.scheme, self.server_host, path, params, query, fragment) = urlparse.urlparse(uri) if not query: path = path.split('?') if self._is_valid_path(path[0]): self.path = path[0] self.query = path[1] return elif self._is_valid_path(path): self.path = path self.query = query return reason = (_('Badly formed VMware datastore URI %(uri)s.') % {'uri': uri}) LOG.debug(reason) raise exception.BadStoreUri(reason) class Store(glance.store.base.Store): """An implementation of the VMware datastore adapter.""" def get_schemes(self): return (STORE_SCHEME,) def configure(self): self.scheme = STORE_SCHEME self.server_host = self._option_get('vmware_server_host') self.server_username = self._option_get('vmware_server_username') self.server_password = self._option_get('vmware_server_password') self.api_retry_count = CONF.vmware_api_retry_count self.task_poll_interval = CONF.vmware_task_poll_interval self.api_insecure = CONF.vmware_api_insecure self._session = api.VMwareAPISession(self.server_host, self.server_username, self.server_password, self.api_retry_count, self.task_poll_interval) self._service_content = self._session.vim.service_content def configure_add(self): self.datacenter_path = CONF.vmware_datacenter_path self.datastore_name = self._option_get('vmware_datastore_name') global _datastore_info_valid if not _datastore_info_valid: search_index_moref = self._service_content.searchIndex inventory_path = ('%s/datastore/%s' % (self.datacenter_path, self.datastore_name)) ds_moref = self._session.invoke_api(self._session.vim, 'FindByInventoryPath', search_index_moref, inventoryPath=inventory_path) if ds_moref is None: reason = (_("Could not find datastore %(ds_name)s " "in datacenter %(dc_path)s") % {'ds_name': self.datastore_name, 'dc_path': self.datacenter_path}) raise exception.BadStoreConfiguration( store_name='vmware_datastore', reason=reason) else: _datastore_info_valid = True self.store_image_dir = CONF.vmware_store_image_dir def _option_get(self, param): result = getattr(CONF, param) if not result: reason = (_("Could not find %(param)s in configuration " "options.") % {'param': param}) raise exception.BadStoreConfiguration( store_name='vmware_datastore', reason=reason) return result def _build_vim_cookie_header(self, vim_cookies): """Build ESX host session cookie header.""" if len(list(vim_cookies)) > 0: cookie = list(vim_cookies)[0] return cookie.name + '=' + cookie.value def add(self, image_id, image_file, image_size): """Stores an image file with supplied identifier to the backend storage system and returns a tuple containing information about the stored image. :param image_id: The opaque image identifier :param image_file: The image data to write, as a file-like object :param image_size: The size of the image data to write, in bytes :retval tuple of URL in backing store, bytes written, checksum and a dictionary with storage system specific information :raises `glance.common.exception.Duplicate` if the image already existed `glance.common.exception.UnexpectedStatus` if the upload request returned an unexpected status. The expected responses are 201 Created and 200 OK. """ checksum = hashlib.md5() image_file = _Reader(image_file, checksum) loc = StoreLocation({'scheme': self.scheme, 'server_host': self.server_host, 'image_dir': self.store_image_dir, 'datacenter_path': self.datacenter_path, 'datastore_name': self.datastore_name, 'image_id': image_id}) cookie = self._build_vim_cookie_header( self._session.vim.client.options.transport.cookiejar) headers = {'Cookie': cookie, 'Content-Length': image_size} try: conn = self._get_http_conn('PUT', loc, headers, content=image_file) res = conn.getresponse() except Exception: with excutils.save_and_reraise_exception(): LOG.exception(_('Failed to upload content of image ' '%(image)s') % {'image': image_id}) if res.status == httplib.CONFLICT: raise exception.Duplicate(_("Image file %(image_id)s already " "exists!") % {'image_id': image_id}) if res.status not in (httplib.CREATED, httplib.OK): msg = (_('Failed to upload content of image %(image)s') % {'image': image_id}) LOG.error(msg) raise exception.UnexpectedStatus(status=res.status, body=res.read()) return (loc.get_uri(), image_file.size, checksum.hexdigest(), {}) def get(self, location): """Takes a `glance.store.location.Location` object that indicates where to find the image file, and returns a tuple of generator (for reading the image file) and image_size :param location: `glance.store.location.Location` object, supplied from glance.store.location.get_location_from_uri() """ cookie = self._build_vim_cookie_header( self._session.vim.client.options.transport.cookiejar) conn, resp, content_length = self._query(location, 'GET', headers={'Cookie': cookie}) iterator = http_response_iterator(conn, resp, self.CHUNKSIZE) class ResponseIndexable(glance.store.Indexable): def another(self): try: return self.wrapped.next() except StopIteration: return '' return (ResponseIndexable(iterator, content_length), content_length) def get_size(self, location): """Takes a `glance.store.location.Location` object that indicates where to find the image file, and returns the size :param location: `glance.store.location.Location` object, supplied from glance.store.location.get_location_from_uri() """ cookie = self._build_vim_cookie_header( self._session.vim.client.options.transport.cookiejar) return self._query(location, 'HEAD', headers={'Cookie': cookie})[2] def delete(self, location): """Takes a `glance.store.location.Location` object that indicates where to find the image file to delete :location `glance.store.location.Location` object, supplied from glance.store.location.get_location_from_uri() :raises NotFound if image does not exist """ file_path = '[%s] %s' % ( self.datastore_name, location.store_location.path[len(DS_URL_PREFIX):]) search_index_moref = self._service_content.searchIndex dc_moref = self._session.invoke_api(self._session.vim, 'FindByInventoryPath', search_index_moref, inventoryPath=self.datacenter_path) delete_task = self._session.invoke_api( self._session.vim, 'DeleteDatastoreFile_Task', self._service_content.fileManager, name=file_path, datacenter=dc_moref) try: self._session.wait_for_task(delete_task) except Exception: with excutils.save_and_reraise_exception(): LOG.exception(_('Failed to delete image %(image)s content.') % {'image': location.image_id}) def _query(self, location, method, headers, depth=0): if depth > MAX_REDIRECTS: msg = (_("The HTTP URL exceeded %(max_redirects)s maximum " "redirects.") % {'max_redirects': MAX_REDIRECTS}) LOG.debug(msg) raise exception.MaxRedirectsExceeded(redirects=MAX_REDIRECTS) loc = location.store_location try: conn = self._get_http_conn(method, loc, headers) resp = conn.getresponse() except Exception: with excutils.save_and_reraise_exception(): LOG.exception(_('Failed to access image %(image)s content.') % {'image': location.image_id}) if resp.status >= 400: if resp.status == httplib.NOT_FOUND: msg = _('VMware datastore could not find image at URI.') LOG.debug(msg) raise exception.NotFound(msg) msg = (_('HTTP request returned a %(status)s status code.') % {'status': resp.status}) LOG.debug(msg) raise exception.BadStoreUri(msg) location_header = resp.getheader('location') if location_header: if resp.status not in (301, 302): msg = (_("The HTTP URL %(path)s attempted to redirect " "with an invalid %(status)s status code.") % {'path': loc.path, 'status': resp.status}) LOG.debug(msg) raise exception.BadStoreUri(msg) location_class = glance.store.location.Location new_loc = location_class(location.store_name, location.store_location.__class__, uri=location_header, image_id=location.image_id, store_specs=location.store_specs) return self._query(new_loc, method, depth + 1) content_length = int(resp.getheader('content-length', 0)) return (conn, resp, content_length) def _get_http_conn(self, method, loc, headers, content=None): conn_class = self._get_http_conn_class() conn = conn_class(loc.server_host) url = urlparse.quote('%s?%s' % (loc.path, loc.query)) conn.request(method, url, content, headers) return conn def _get_http_conn_class(self): if self.api_insecure: return httplib.HTTPConnection return httplib.HTTPSConnection glance-2014.1/glance/store/filesystem.py0000664000175400017540000004377612323736230021335 0ustar jenkinsjenkins00000000000000# Copyright 2010 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ A simple filesystem-backed store """ import errno import hashlib import os from oslo.config import cfg import six import six.moves.urllib.parse as urlparse from glance.common import exception from glance.common import utils from glance.openstack.common import jsonutils import glance.openstack.common.log as logging from glance.openstack.common import processutils import glance.store import glance.store.base import glance.store.location LOG = logging.getLogger(__name__) filesystem_opts = [ cfg.StrOpt('filesystem_store_datadir', help=_('Directory to which the Filesystem backend ' 'store writes images.')), cfg.MultiStrOpt('filesystem_store_datadirs', help=_("List of directories and its priorities to which " "the Filesystem backend store writes images.")), cfg.StrOpt('filesystem_store_metadata_file', help=_("The path to a file which contains the " "metadata to be returned with any location " "associated with this store. The file must " "contain a valid JSON dict."))] CONF = cfg.CONF CONF.register_opts(filesystem_opts) class StoreLocation(glance.store.location.StoreLocation): """Class describing a Filesystem URI""" def process_specs(self): self.scheme = self.specs.get('scheme', 'file') self.path = self.specs.get('path') def get_uri(self): return "file://%s" % self.path def parse_uri(self, uri): """ Parse URLs. This method fixes an issue where credentials specified in the URL are interpreted differently in Python 2.6.1+ than prior versions of Python. """ pieces = urlparse.urlparse(uri) assert pieces.scheme in ('file', 'filesystem') self.scheme = pieces.scheme path = (pieces.netloc + pieces.path).strip() if path == '': reason = _("No path specified in URI: %s") % uri LOG.debug(reason) raise exception.BadStoreUri('No path specified') self.path = path class ChunkedFile(object): """ We send this back to the Glance API server as something that can iterate over a large file """ CHUNKSIZE = 65536 def __init__(self, filepath): self.filepath = filepath self.fp = open(self.filepath, 'rb') def __iter__(self): """Return an iterator over the image file""" try: if self.fp: while True: chunk = self.fp.read(ChunkedFile.CHUNKSIZE) if chunk: yield chunk else: break finally: self.close() def close(self): """Close the internal file pointer""" if self.fp: self.fp.close() self.fp = None class Store(glance.store.base.Store): def get_schemes(self): return ('file', 'filesystem') def _check_write_permission(self, datadir): """ Checks if directory created to write image files has write permission. :datadir is a directory path in which glance wites image files. :raise BadStoreConfiguration exception if datadir is read-only. """ if not os.access(datadir, os.W_OK): msg = (_("Permission to write in %s denied") % datadir) LOG.exception(msg) raise exception.BadStoreConfiguration( store_name="filesystem", reason=msg) def _create_image_directories(self, directory_paths): """ Create directories to write image files if it does not exist. :directory_paths is a list of directories belonging to glance store. :raise BadStoreConfiguration exception if creating a directory fails. """ for datadir in directory_paths: if os.path.exists(datadir): self._check_write_permission(datadir) else: msg = _("Directory to write image files does not exist " "(%s). Creating.") % datadir LOG.info(msg) try: os.makedirs(datadir) self._check_write_permission(datadir) except (IOError, OSError): if os.path.exists(datadir): # NOTE(markwash): If the path now exists, some other # process must have beat us in the race condition. # But it doesn't hurt, so we can safely ignore # the error. self._check_write_permission(datadir) continue reason = _("Unable to create datadir: %s") % datadir LOG.error(reason) raise exception.BadStoreConfiguration( store_name="filesystem", reason=reason) def configure_add(self): """ Configure the Store to use the stored configuration options Any store that needs special configuration should implement this method. If the store was not able to successfully configure itself, it should raise `exception.BadStoreConfiguration` """ if not (CONF.filesystem_store_datadir or CONF.filesystem_store_datadirs): reason = (_("Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option")) LOG.error(reason) raise exception.BadStoreConfiguration(store_name="filesystem", reason=reason) if CONF.filesystem_store_datadir and CONF.filesystem_store_datadirs: reason = (_("Specify either 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option")) LOG.error(reason) raise exception.BadStoreConfiguration(store_name="filesystem", reason=reason) self.multiple_datadirs = False directory_paths = set() if CONF.filesystem_store_datadir: self.datadir = CONF.filesystem_store_datadir directory_paths.add(self.datadir) else: self.multiple_datadirs = True self.priority_data_map = {} for datadir in CONF.filesystem_store_datadirs: (datadir_path, priority) = self._get_datadir_path_and_priority(datadir) self._check_directory_paths(datadir_path, directory_paths) directory_paths.add(datadir_path) self.priority_data_map.setdefault(int(priority), []).append(datadir_path) self.priority_list = sorted(self.priority_data_map, reverse=True) self._create_image_directories(directory_paths) def _check_directory_paths(self, datadir_path, directory_paths): """ Checks if directory_path is already present in directory_paths. :datadir_path is directory path. :datadir_paths is set of all directory paths. :raise BadStoreConfiguration exception if same directory path is already present in directory_paths. """ if datadir_path in directory_paths: msg = (_("Directory %(datadir_path)s specified " "multiple times in filesystem_store_datadirs " "option of filesystem configuration") % {'datadir_path': datadir_path}) LOG.exception(msg) raise exception.BadStoreConfiguration( store_name="filesystem", reason=msg) def _get_datadir_path_and_priority(self, datadir): """ Gets directory paths and its priority from filesystem_store_datadirs option in glance-api.conf. :datadir is directory path with its priority. :returns datadir_path as directory path priority as priority associated with datadir_path :raise BadStoreConfiguration exception if priority is invalid or empty directory path is specified. """ priority = 0 parts = map(lambda x: x.strip(), datadir.rsplit(":", 1)) datadir_path = parts[0] if len(parts) == 2 and parts[1]: priority = parts[1] if not priority.isdigit(): msg = (_("Invalid priority value %(priority)s in " "filesystem configuration") % {'priority': priority}) LOG.exception(msg) raise exception.BadStoreConfiguration( store_name="filesystem", reason=msg) if not datadir_path: msg = _("Invalid directory specified in filesystem configuration") LOG.exception(msg) raise exception.BadStoreConfiguration( store_name="filesystem", reason=msg) return datadir_path, priority @staticmethod def _resolve_location(location): filepath = location.store_location.path if not os.path.exists(filepath): raise exception.NotFound(_("Image file %s not found") % filepath) filesize = os.path.getsize(filepath) return filepath, filesize def _get_metadata(self): if CONF.filesystem_store_metadata_file is None: return {} try: with open(CONF.filesystem_store_metadata_file, 'r') as fptr: metadata = jsonutils.load(fptr) glance.store.check_location_metadata(metadata) return metadata except glance.store.BackendException as bee: LOG.error(_('The JSON in the metadata file %(file)s could not be ' 'used: %(error)s An empty dictionary will be ' 'returned to the client.') % {'file': CONF.filesystem_store_metadata_file, 'error': six.text_type(bee)}) return {} except IOError as ioe: LOG.error(_('The path for the metadata file %(file)s could not be ' 'opened: %(error)s An empty dictionary will be ' 'returned to the client.') % {'file': CONF.filesystem_store_metadata_file, 'error': six.text_type(ioe)}) return {} except Exception as ex: LOG.exception(_('An error occurred processing the storage systems ' 'meta data file: %s. An empty dictionary will be ' 'returned to the client.') % six.text_type(ex)) return {} def get(self, location): """ Takes a `glance.store.location.Location` object that indicates where to find the image file, and returns a tuple of generator (for reading the image file) and image_size :param location `glance.store.location.Location` object, supplied from glance.store.location.get_location_from_uri() :raises `glance.exception.NotFound` if image does not exist """ filepath, filesize = self._resolve_location(location) msg = _("Found image at %s. Returning in ChunkedFile.") % filepath LOG.debug(msg) return (ChunkedFile(filepath), filesize) def get_size(self, location): """ Takes a `glance.store.location.Location` object that indicates where to find the image file and returns the image size :param location `glance.store.location.Location` object, supplied from glance.store.location.get_location_from_uri() :raises `glance.exception.NotFound` if image does not exist :rtype int """ filepath, filesize = self._resolve_location(location) msg = _("Found image at %s.") % filepath LOG.debug(msg) return filesize def delete(self, location): """ Takes a `glance.store.location.Location` object that indicates where to find the image file to delete :location `glance.store.location.Location` object, supplied from glance.store.location.get_location_from_uri() :raises NotFound if image does not exist :raises Forbidden if cannot delete because of permissions """ loc = location.store_location fn = loc.path if os.path.exists(fn): try: LOG.debug(_("Deleting image at %(fn)s"), {'fn': fn}) os.unlink(fn) except OSError: raise exception.Forbidden(_("You cannot delete file %s") % fn) else: raise exception.NotFound(_("Image file %s does not exist") % fn) def _get_capacity_info(self, mount_point): """Calculates total available space for given mount point. :mount_point is path of glance data directory """ #Calculate total available space df = processutils.execute("df", "--block-size=1", mount_point)[0].strip("'\n'") total_available_space = int(df.split('\n')[1].split()[3]) return max(0, total_available_space) def _find_best_datadir(self, image_size): """Finds the best datadir by priority and free space. Traverse directories returning the first one that has sufficient free space, in priority order. If two suitable directories have the same priority, choose the one with the most free space available. :image_size size of image being uploaded. :returns best_datadir as directory path of the best priority datadir. :raises exception.StorageFull if there is no datadir in self.priority_data_map that can accommodate the image. """ if not self.multiple_datadirs: return self.datadir best_datadir = None max_free_space = 0 for priority in self.priority_list: for datadir in self.priority_data_map.get(priority): free_space = self._get_capacity_info(datadir) if free_space >= image_size and free_space > max_free_space: max_free_space = free_space best_datadir = datadir # If datadir is found which can accommodate image and has maximum # free space for the given priority then break the loop, # else continue to lookup further. if best_datadir: break else: msg = (_("There is no enough disk space left on the image " "storage media. requested=%s") % image_size) LOG.exception(msg) raise exception.StorageFull(message=msg) return best_datadir def add(self, image_id, image_file, image_size): """ Stores an image file with supplied identifier to the backend storage system and returns a tuple containing information about the stored image. :param image_id: The opaque image identifier :param image_file: The image data to write, as a file-like object :param image_size: The size of the image data to write, in bytes :retval tuple of URL in backing store, bytes written, checksum and a dictionary with storage system specific information :raises `glance.common.exception.Duplicate` if the image already existed :note By default, the backend writes the image data to a file `//`, where is the value of the filesystem_store_datadir configuration option and is the supplied image ID. """ datadir = self._find_best_datadir(image_size) filepath = os.path.join(datadir, str(image_id)) if os.path.exists(filepath): raise exception.Duplicate(_("Image file %s already exists!") % filepath) checksum = hashlib.md5() bytes_written = 0 try: with open(filepath, 'wb') as f: for buf in utils.chunkreadable(image_file, ChunkedFile.CHUNKSIZE): bytes_written += len(buf) checksum.update(buf) f.write(buf) except IOError as e: if e.errno != errno.EACCES: self._delete_partial(filepath, image_id) exceptions = {errno.EFBIG: exception.StorageFull(), errno.ENOSPC: exception.StorageFull(), errno.EACCES: exception.StorageWriteDenied()} raise exceptions.get(e.errno, e) except Exception: self._delete_partial(filepath, image_id) raise checksum_hex = checksum.hexdigest() metadata = self._get_metadata() LOG.debug(_("Wrote %(bytes_written)d bytes to %(filepath)s with " "checksum %(checksum_hex)s"), {'bytes_written': bytes_written, 'filepath': filepath, 'checksum_hex': checksum_hex}) return ('file://%s' % filepath, bytes_written, checksum_hex, metadata) @staticmethod def _delete_partial(filepath, id): try: os.unlink(filepath) except Exception as e: msg = _('Unable to remove partial image data for image %(id)s: ' '%(error)s') LOG.error(msg % {'id': id, 'error': e}) glance-2014.1/glance/store/http.py0000664000175400017540000001504412323736226020120 0ustar jenkinsjenkins00000000000000# Copyright 2010 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import httplib import six.moves.urllib.parse as urlparse from glance.common import exception import glance.openstack.common.log as logging import glance.store.base import glance.store.location LOG = logging.getLogger(__name__) MAX_REDIRECTS = 5 class StoreLocation(glance.store.location.StoreLocation): """Class describing an HTTP(S) URI""" def process_specs(self): self.scheme = self.specs.get('scheme', 'http') self.netloc = self.specs['netloc'] self.user = self.specs.get('user') self.password = self.specs.get('password') self.path = self.specs.get('path') def _get_credstring(self): if self.user: return '%s:%s@' % (self.user, self.password) return '' def get_uri(self): return "%s://%s%s%s" % ( self.scheme, self._get_credstring(), self.netloc, self.path) def parse_uri(self, uri): """ Parse URLs. This method fixes an issue where credentials specified in the URL are interpreted differently in Python 2.6.1+ than prior versions of Python. """ pieces = urlparse.urlparse(uri) assert pieces.scheme in ('https', 'http') self.scheme = pieces.scheme netloc = pieces.netloc path = pieces.path try: if '@' in netloc: creds, netloc = netloc.split('@') else: creds = None except ValueError: # Python 2.6.1 compat # see lp659445 and Python issue7904 if '@' in path: creds, path = path.split('@') else: creds = None if creds: try: self.user, self.password = creds.split(':') except ValueError: reason = (_("Credentials '%s' not well-formatted.") % "".join(creds)) LOG.debug(reason) raise exception.BadStoreUri() else: self.user = None if netloc == '': reason = _("No address specified in HTTP URL") LOG.debug(reason) raise exception.BadStoreUri(message=reason) self.netloc = netloc self.path = path def http_response_iterator(conn, response, size): """ Return an iterator for a file-like object. :param conn: HTTP(S) Connection :param response: httplib.HTTPResponse object :param size: Chunk size to iterate with """ chunk = response.read(size) while chunk: yield chunk chunk = response.read(size) conn.close() class Store(glance.store.base.Store): """An implementation of the HTTP(S) Backend Adapter""" def get(self, location): """ Takes a `glance.store.location.Location` object that indicates where to find the image file, and returns a tuple of generator (for reading the image file) and image_size :param location `glance.store.location.Location` object, supplied from glance.store.location.get_location_from_uri() """ conn, resp, content_length = self._query(location, 'GET') iterator = http_response_iterator(conn, resp, self.CHUNKSIZE) class ResponseIndexable(glance.store.Indexable): def another(self): try: return self.wrapped.next() except StopIteration: return '' return (ResponseIndexable(iterator, content_length), content_length) def get_schemes(self): return ('http', 'https') def get_size(self, location): """ Takes a `glance.store.location.Location` object that indicates where to find the image file, and returns the size :param location `glance.store.location.Location` object, supplied from glance.store.location.get_location_from_uri() """ try: return self._query(location, 'HEAD')[2] except Exception: return 0 def _query(self, location, verb, depth=0): if depth > MAX_REDIRECTS: reason = (_("The HTTP URL exceeded %s maximum " "redirects.") % MAX_REDIRECTS) LOG.debug(reason) raise exception.MaxRedirectsExceeded(redirects=MAX_REDIRECTS) loc = location.store_location conn_class = self._get_conn_class(loc) conn = conn_class(loc.netloc) conn.request(verb, loc.path, "", {}) resp = conn.getresponse() # Check for bad status codes if resp.status >= 400: reason = _("HTTP URL returned a %s status code.") % resp.status LOG.debug(reason) raise exception.BadStoreUri(loc.path, reason) location_header = resp.getheader("location") if location_header: if resp.status not in (301, 302): reason = (_("The HTTP URL attempted to redirect with an " "invalid %s status code.") % resp.status) LOG.debug(reason) raise exception.BadStoreUri(loc.path, reason) location_class = glance.store.location.Location new_loc = location_class(location.store_name, location.store_location.__class__, uri=location_header, image_id=location.image_id, store_specs=location.store_specs) return self._query(new_loc, verb, depth + 1) content_length = int(resp.getheader('content-length', 0)) return (conn, resp, content_length) def _get_conn_class(self, loc): """ Returns connection class for accessing the resource. Useful for dependency injection and stubouts in testing... """ return {'http': httplib.HTTPConnection, 'https': httplib.HTTPSConnection}[loc.scheme] glance-2014.1/glance/store/location.py0000664000175400017540000001374312323736226020755 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ A class that describes the location of an image in Glance. In Glance, an image can either be **stored** in Glance, or it can be **registered** in Glance but actually be stored somewhere else. We needed a class that could support the various ways that Glance describes where exactly an image is stored. An image in Glance has two location properties: the image URI and the image storage URI. The image URI is essentially the permalink identifier for the image. It is displayed in the output of various Glance API calls and, while read-only, is entirely user-facing. It shall **not** contain any security credential information at all. The Glance image URI shall be the host:port of that Glance API server along with /images/. The Glance storage URI is an internal URI structure that Glance uses to maintain critical information about how to access the images that it stores in its storage backends. It **may contain** security credentials and is **not** user-facing. """ import six.moves.urllib.parse as urlparse from glance.common import exception import glance.openstack.common.log as logging LOG = logging.getLogger(__name__) SCHEME_TO_CLS_MAP = {} def get_location_from_uri(uri): """ Given a URI, return a Location object that has had an appropriate store parse the URI. :param uri: A URI that could come from the end-user in the Location attribute/header Example URIs: https://user:pass@example.com:80/images/some-id http://images.oracle.com/123456 swift://example.com/container/obj-id swift://user:account:pass@authurl.com/container/obj-id swift+http://user:account:pass@authurl.com/container/obj-id s3://accesskey:secretkey@s3.amazonaws.com/bucket/key-id s3+https://accesskey:secretkey@s3.amazonaws.com/bucket/key-id file:///var/lib/glance/images/1 cinder://volume-id vsphere://server_host/folder/file_path?dcPath=dc_path&dsName=ds_name """ pieces = urlparse.urlparse(uri) if pieces.scheme not in SCHEME_TO_CLS_MAP.keys(): raise exception.UnknownScheme(scheme=pieces.scheme) scheme_info = SCHEME_TO_CLS_MAP[pieces.scheme] return Location(pieces.scheme, uri=uri, store_location_class=scheme_info['location_class']) def register_scheme_map(scheme_map): """ Given a mapping of 'scheme' to store_name, adds the mapping to the known list of schemes if it does not already exist. """ for (k, v) in scheme_map.items(): if k not in SCHEME_TO_CLS_MAP: LOG.debug(_("Registering scheme %(k)s with %(v)s") % {'k': k, 'v': v}) SCHEME_TO_CLS_MAP[k] = v class Location(object): """ Class describing the location of an image that Glance knows about """ def __init__(self, store_name, store_location_class, uri=None, image_id=None, store_specs=None): """ Create a new Location object. :param store_name: The string identifier/scheme of the storage backend :param store_location_class: The store location class to use for this location instance. :param image_id: The identifier of the image in whatever storage backend is used. :param uri: Optional URI to construct location from :param store_specs: Dictionary of information about the location of the image that is dependent on the backend store """ self.store_name = store_name self.image_id = image_id self.store_specs = store_specs or {} self.store_location = store_location_class(self.store_specs) if uri: self.store_location.parse_uri(uri) def get_store_uri(self): """ Returns the Glance image URI, which is the host:port of the API server along with /images/ """ return self.store_location.get_uri() def get_uri(self): return None class StoreLocation(object): """ Base class that must be implemented by each store """ def __init__(self, store_specs): self.specs = store_specs if self.specs: self.process_specs() def process_specs(self): """ Subclasses should implement any processing of the self.specs collection such as storing credentials and possibly establishing connections. """ pass def get_uri(self): """ Subclasses should implement a method that returns an internal URI that, when supplied to the StoreLocation instance, can be interpreted by the StoreLocation's parse_uri() method. The URI returned from this method shall never be public and only used internally within Glance, so it is fine to encode credentials in this URI. """ raise NotImplementedError("StoreLocation subclass must implement " "get_uri()") def parse_uri(self, uri): """ Subclasses should implement a method that accepts a string URI and sets appropriate internal fields such that a call to get_uri() will return a proper internal URI """ raise NotImplementedError("StoreLocation subclass must implement " "parse_uri()") glance-2014.1/glance/store/__init__.py0000664000175400017540000006511012323736230020672 0ustar jenkinsjenkins00000000000000# Copyright 2010-2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import collections import copy import sys from oslo.config import cfg import six from glance.common import exception from glance.common import utils import glance.context import glance.domain.proxy from glance.openstack.common import importutils import glance.openstack.common.log as logging from glance import scrubber from glance.store import location LOG = logging.getLogger(__name__) store_opts = [ cfg.ListOpt('known_stores', default=[ 'glance.store.filesystem.Store', 'glance.store.http.Store' ], help=_('List of which store classes and store class locations ' 'are currently known to glance at startup.')), cfg.StrOpt('default_store', default='file', help=_("Default scheme to use to store image data. The " "scheme must be registered by one of the stores " "defined by the 'known_stores' config option.")), cfg.StrOpt('scrubber_datadir', default='/var/lib/glance/scrubber', help=_('Directory that the scrubber will use to track ' 'information about what to delete. ' 'Make sure this is set in glance-api.conf and ' 'glance-scrubber.conf.')), cfg.BoolOpt('delayed_delete', default=False, help=_('Turn on/off delayed delete.')), cfg.BoolOpt('use_user_token', default=True, help=_('Whether to pass through the user token when ' 'making requests to the registry.')), cfg.IntOpt('scrub_time', default=0, help=_('The amount of time in seconds to delay before ' 'performing a delete.')), ] REGISTERED_STORES = set() CONF = cfg.CONF CONF.register_opts(store_opts) _ALL_STORES = [ 'glance.store.filesystem.Store', 'glance.store.http.Store', 'glance.store.rbd.Store', 'glance.store.s3.Store', 'glance.store.swift.Store', 'glance.store.sheepdog.Store', 'glance.store.cinder.Store', 'glance.store.gridfs.Store', 'glance.store.vmware_datastore.Store' ] class BackendException(Exception): pass class UnsupportedBackend(BackendException): pass class Indexable(object): """ Wrapper that allows an iterator or filelike be treated as an indexable data structure. This is required in the case where the return value from Store.get() is passed to Store.add() when adding a Copy-From image to a Store where the client library relies on eventlet GreenSockets, in which case the data to be written is indexed over. """ def __init__(self, wrapped, size): """ Initialize the object :param wrappped: the wrapped iterator or filelike. :param size: the size of data available """ self.wrapped = wrapped self.size = int(size) if size else (wrapped.len if hasattr(wrapped, 'len') else 0) self.cursor = 0 self.chunk = None def __iter__(self): """ Delegate iteration to the wrapped instance. """ for self.chunk in self.wrapped: yield self.chunk def __getitem__(self, i): """ Index into the next chunk (or previous chunk in the case where the last data returned was not fully consumed). :param i: a slice-to-the-end """ start = i.start if isinstance(i, slice) else i if start < self.cursor: return self.chunk[(start - self.cursor):] self.chunk = self.another() if self.chunk: self.cursor += len(self.chunk) return self.chunk def another(self): """Implemented by subclasses to return the next element""" raise NotImplementedError def getvalue(self): """ Return entire string value... used in testing """ return self.wrapped.getvalue() def __len__(self): """ Length accessor. """ return self.size def _register_stores(store_classes): """ Given a set of store names, add them to a globally available set of store names. """ for store_cls in store_classes: REGISTERED_STORES.add(store_cls.__module__.split('.')[2]) # NOTE (spredzy): The actual class name is filesystem but in order # to maintain backward compatibility we need to keep the 'file' store # as a known store if 'filesystem' in REGISTERED_STORES: REGISTERED_STORES.add('file') def _get_store_class(store_entry): store_cls = None try: LOG.debug("Attempting to import store %s", store_entry) store_cls = importutils.import_class(store_entry) except exception.NotFound: raise BackendException('Unable to load store. ' 'Could not find a class named %s.' % store_entry) return store_cls def create_stores(): """ Registers all store modules and all schemes from the given config. Duplicates are not re-registered. """ store_count = 0 store_classes = set() for store_entry in set(CONF.known_stores + _ALL_STORES): store_entry = store_entry.strip() if not store_entry: continue store_cls = _get_store_class(store_entry) try: store_instance = store_cls() except exception.BadStoreConfiguration as e: if store_entry in CONF.known_stores: LOG.warn(_("%s Skipping store driver.") % unicode(e)) continue finally: # NOTE(flaper87): To be removed in Juno if store_entry not in CONF.known_stores: LOG.deprecated(_("%s not found in `known_store`. " "Stores need to be explicitly enabled in " "the configuration file.") % store_entry) schemes = store_instance.get_schemes() if not schemes: raise BackendException('Unable to register store %s. ' 'No schemes associated with it.' % store_cls) else: if store_cls not in store_classes: LOG.debug("Registering store %s with schemes %s", store_cls, schemes) store_classes.add(store_cls) scheme_map = {} for scheme in schemes: loc_cls = store_instance.get_store_location_class() scheme_map[scheme] = { 'store_class': store_cls, 'location_class': loc_cls, } location.register_scheme_map(scheme_map) store_count += 1 else: LOG.debug("Store %s already registered", store_cls) _register_stores(store_classes) return store_count def verify_default_store(): scheme = cfg.CONF.default_store context = glance.context.RequestContext() try: get_store_from_scheme(context, scheme) except exception.UnknownScheme: msg = _("Store for scheme %s not found") % scheme raise RuntimeError(msg) def get_known_schemes(): """Returns list of known schemes""" return location.SCHEME_TO_CLS_MAP.keys() def get_known_stores(): """Returns list of known stores""" return list(REGISTERED_STORES) def get_store_from_scheme(context, scheme, loc=None): """ Given a scheme, return the appropriate store object for handling that scheme. """ if scheme not in location.SCHEME_TO_CLS_MAP: raise exception.UnknownScheme(scheme=scheme) scheme_info = location.SCHEME_TO_CLS_MAP[scheme] store = scheme_info['store_class'](context, loc) return store def get_store_from_uri(context, uri, loc=None): """ Given a URI, return the store object that would handle operations on the URI. :param uri: URI to analyze """ scheme = uri[0:uri.find('/') - 1] store = get_store_from_scheme(context, scheme, loc) return store def get_from_backend(context, uri, **kwargs): """Yields chunks of data from backend specified by uri""" loc = location.get_location_from_uri(uri) store = get_store_from_uri(context, uri, loc) try: return store.get(loc) except NotImplementedError: raise exception.StoreGetNotSupported def get_size_from_backend(context, uri): """Retrieves image size from backend specified by uri""" loc = location.get_location_from_uri(uri) store = get_store_from_uri(context, uri, loc) return store.get_size(loc) def delete_from_backend(context, uri, **kwargs): """Removes chunks of data from backend specified by uri""" loc = location.get_location_from_uri(uri) store = get_store_from_uri(context, uri, loc) try: return store.delete(loc) except NotImplementedError: raise exception.StoreDeleteNotSupported def get_store_from_location(uri): """ Given a location (assumed to be a URL), attempt to determine the store from the location. We use here a simple guess that the scheme of the parsed URL is the store... :param uri: Location to check for the store """ loc = location.get_location_from_uri(uri) return loc.store_name def safe_delete_from_backend(context, uri, image_id, **kwargs): """Given a uri, delete an image from the store.""" try: return delete_from_backend(context, uri, **kwargs) except exception.NotFound: msg = _('Failed to delete image %s in store from URI') LOG.warn(msg % image_id) except exception.StoreDeleteNotSupported as e: LOG.warn(six.text_type(e)) except UnsupportedBackend: exc_type = sys.exc_info()[0].__name__ msg = (_('Failed to delete image %(image_id)s from store ' '(%(error)s)') % {'image_id': image_id, 'error': exc_type}) LOG.error(msg) def schedule_delayed_delete_from_backend(context, uri, image_id, **kwargs): """Given a uri, schedule the deletion of an image location.""" (file_queue, _db_queue) = scrubber.get_scrub_queues() # NOTE(zhiyan): Defautly ask glance-api store using file based queue. # In future we can change it using DB based queued instead, # such as using image location's status to saving pending delete flag # when that property be added. if CONF.use_user_token is False: context = None file_queue.add_location(image_id, uri, user_context=context) def delete_image_from_backend(context, store_api, image_id, uri): if CONF.delayed_delete: store_api.schedule_delayed_delete_from_backend(context, uri, image_id) else: store_api.safe_delete_from_backend(context, uri, image_id) def check_location_metadata(val, key=''): if isinstance(val, dict): for key in val: check_location_metadata(val[key], key=key) elif isinstance(val, list): ndx = 0 for v in val: check_location_metadata(v, key='%s[%d]' % (key, ndx)) ndx = ndx + 1 elif not isinstance(val, unicode): raise BackendException(_("The image metadata key %(key)s has an " "invalid type of %(val)s. Only dict, list, " "and unicode are supported.") % {'key': key, 'val': type(val)}) def store_add_to_backend(image_id, data, size, store): """ A wrapper around a call to each stores add() method. This gives glance a common place to check the output :param image_id: The image add to which data is added :param data: The data to be stored :param size: The length of the data in bytes :param store: The store to which the data is being added :return: The url location of the file, the size amount of data, the checksum of the data the storage systems metadata dictionary for the location """ (location, size, checksum, metadata) = store.add(image_id, data, size) if metadata is not None: if not isinstance(metadata, dict): msg = (_("The storage driver %(store)s returned invalid metadata " "%(metadata)s. This must be a dictionary type") % {'store': six.text_type(store), 'metadata': six.text_type(metadata)}) LOG.error(msg) raise BackendException(msg) try: check_location_metadata(metadata) except BackendException as e: e_msg = (_("A bad metadata structure was returned from the " "%(store)s storage driver: %(metadata)s. %(error)s.") % {'store': six.text_type(store), 'metadata': six.text_type(metadata), 'error': six.text_type(e)}) LOG.error(e_msg) raise BackendException(e_msg) return (location, size, checksum, metadata) def add_to_backend(context, scheme, image_id, data, size): store = get_store_from_scheme(context, scheme) try: return store_add_to_backend(image_id, data, size, store) except NotImplementedError: raise exception.StoreAddNotSupported def set_acls(context, location_uri, public=False, read_tenants=[], write_tenants=[]): loc = location.get_location_from_uri(location_uri) scheme = get_store_from_location(location_uri) store = get_store_from_scheme(context, scheme, loc) try: store.set_acls(loc, public=public, read_tenants=read_tenants, write_tenants=write_tenants) except NotImplementedError: LOG.debug(_("Skipping store.set_acls... not implemented.")) class ImageRepoProxy(glance.domain.proxy.Repo): def __init__(self, image_repo, context, store_api): self.context = context self.store_api = store_api proxy_kwargs = {'context': context, 'store_api': store_api} super(ImageRepoProxy, self).__init__(image_repo, item_proxy_class=ImageProxy, item_proxy_kwargs=proxy_kwargs) def _set_acls(self, image): public = image.visibility == 'public' member_ids = [] if image.locations and not public: member_repo = image.get_member_repo() member_ids = [m.member_id for m in member_repo.list()] for location in image.locations: self.store_api.set_acls(self.context, location['url'], public, read_tenants=member_ids) def add(self, image): result = super(ImageRepoProxy, self).add(image) self._set_acls(image) return result def save(self, image): result = super(ImageRepoProxy, self).save(image) self._set_acls(image) return result def _check_location_uri(context, store_api, uri): """ Check if an image location uri is valid. :param context: Glance request context :param store_api: store API module :param uri: location's uri string """ is_ok = True try: size = store_api.get_size_from_backend(context, uri) # NOTE(zhiyan): Some stores return zero when it catch exception is_ok = size > 0 except (exception.UnknownScheme, exception.NotFound): is_ok = False if not is_ok: raise exception.BadStoreUri(_('Invalid location: %s') % uri) def _check_image_location(context, store_api, location): _check_location_uri(context, store_api, location['url']) store_api.check_location_metadata(location['metadata']) def _set_image_size(context, image, locations): if not image.size: for location in locations: size_from_backend = glance.store.get_size_from_backend( context, location['url']) if size_from_backend: # NOTE(flwang): This assumes all locations have the same size image.size = size_from_backend break class ImageFactoryProxy(glance.domain.proxy.ImageFactory): def __init__(self, factory, context, store_api): self.context = context self.store_api = store_api proxy_kwargs = {'context': context, 'store_api': store_api} super(ImageFactoryProxy, self).__init__(factory, proxy_class=ImageProxy, proxy_kwargs=proxy_kwargs) def new_image(self, **kwargs): locations = kwargs.get('locations', []) for l in locations: _check_image_location(self.context, self.store_api, l) if locations.count(l) > 1: raise exception.DuplicateLocation(location=l['url']) return super(ImageFactoryProxy, self).new_image(**kwargs) class StoreLocations(collections.MutableSequence): """ The proxy for store location property. It takes responsibility for: 1. Location uri correctness checking when adding a new location. 2. Remove the image data from the store when a location is removed from an image. """ def __init__(self, image_proxy, value): self.image_proxy = image_proxy if isinstance(value, list): self.value = value else: self.value = list(value) def append(self, location): # NOTE(flaper87): Insert this # location at the very end of # the value list. self.insert(len(self.value), location) def extend(self, other): if isinstance(other, StoreLocations): locations = other.value else: locations = list(other) for location in locations: self.append(location) def insert(self, i, location): _check_image_location(self.image_proxy.context, self.image_proxy.store_api, location) if location in self.value: raise exception.DuplicateLocation(location=location['url']) self.value.insert(i, location) _set_image_size(self.image_proxy.context, self.image_proxy, [location]) def pop(self, i=-1): location = self.value.pop(i) try: delete_image_from_backend(self.image_proxy.context, self.image_proxy.store_api, self.image_proxy.image.image_id, location['url']) except Exception: self.value.insert(i, location) raise return location def count(self, location): return self.value.count(location) def index(self, location, *args): return self.value.index(location, *args) def remove(self, location): if self.count(location): self.pop(self.index(location)) else: self.value.remove(location) def reverse(self): self.value.reverse() # Mutable sequence, so not hashable __hash__ = None def __getitem__(self, i): return self.value.__getitem__(i) def __setitem__(self, i, location): _check_image_location(self.image_proxy.context, self.image_proxy.store_api, location) self.value.__setitem__(i, location) _set_image_size(self.image_proxy.context, self.image_proxy, [location]) def __delitem__(self, i): location = None try: location = self.value.__getitem__(i) except Exception: return self.value.__delitem__(i) delete_image_from_backend(self.image_proxy.context, self.image_proxy.store_api, self.image_proxy.image.image_id, location['url']) self.value.__delitem__(i) def __delslice__(self, i, j): i = max(i, 0) j = max(j, 0) locations = [] try: locations = self.value.__getslice__(i, j) except Exception: return self.value.__delslice__(i, j) for location in locations: delete_image_from_backend(self.image_proxy.context, self.image_proxy.store_api, self.image_proxy.image.image_id, location['url']) self.value.__delitem__(i) def __iadd__(self, other): self.extend(other) return self def __contains__(self, location): return location in self.value def __len__(self): return len(self.value) def __cast(self, other): if isinstance(other, StoreLocations): return other.value else: return other def __cmp__(self, other): return cmp(self.value, self.__cast(other)) def __iter__(self): return iter(self.value) def __copy__(self): return type(self)(self.image_proxy, self.value) def __deepcopy__(self, memo): # NOTE(zhiyan): Only copy location entries, others can be reused. value = copy.deepcopy(self.value, memo) self.image_proxy.image.locations = value return type(self)(self.image_proxy, value) def _locations_proxy(target, attr): """ Make a location property proxy on the image object. :param target: the image object on which to add the proxy :param attr: the property proxy we want to hook """ def get_attr(self): value = getattr(getattr(self, target), attr) return StoreLocations(self, value) def set_attr(self, value): if not isinstance(value, (list, StoreLocations)): raise exception.BadStoreUri(_('Invalid locations: %s') % value) ori_value = getattr(getattr(self, target), attr) if ori_value != value: # NOTE(zhiyan): Enforced locations list was previously empty list. if len(ori_value) > 0: raise exception.Invalid(_('Original locations is not empty: ' '%s') % ori_value) # NOTE(zhiyan): Check locations are all valid. for location in value: _check_image_location(self.context, self.store_api, location) if value.count(location) > 1: raise exception.DuplicateLocation(location=location['url']) _set_image_size(self.context, getattr(self, target), value) return setattr(getattr(self, target), attr, list(value)) def del_attr(self): value = getattr(getattr(self, target), attr) while len(value): delete_image_from_backend(self.context, self.store_api, self.image.image_id, value[0]['url']) del value[0] setattr(getattr(self, target), attr, value) return delattr(getattr(self, target), attr) return property(get_attr, set_attr, del_attr) class ImageProxy(glance.domain.proxy.Image): locations = _locations_proxy('image', 'locations') def __init__(self, image, context, store_api): self.image = image self.context = context self.store_api = store_api proxy_kwargs = { 'context': context, 'image': self, 'store_api': store_api, } super(ImageProxy, self).__init__( image, member_repo_proxy_class=ImageMemberRepoProxy, member_repo_proxy_kwargs=proxy_kwargs) def delete(self): self.image.delete() if self.image.locations: for location in self.image.locations: self.store_api.delete_image_from_backend(self.context, self.store_api, self.image.image_id, location['url']) def set_data(self, data, size=None): if size is None: size = 0 # NOTE(markwash): zero -> unknown size location, size, checksum, loc_meta = self.store_api.add_to_backend( self.context, CONF.default_store, self.image.image_id, utils.CooperativeReader(data), size) self.image.locations = [{'url': location, 'metadata': loc_meta}] self.image.size = size self.image.checksum = checksum self.image.status = 'active' def get_data(self): if not self.image.locations: raise exception.NotFound(_("No image data could be found")) err = None for loc in self.image.locations: try: data, size = self.store_api.get_from_backend(self.context, loc['url']) return data except Exception as e: LOG.warn(_('Get image %(id)s data failed: ' '%(err)s.') % {'id': self.image.image_id, 'err': six.text_type(e)}) err = e # tried all locations LOG.error(_('Glance tried all locations to get data for image %s ' 'but all have failed.') % self.image.image_id) raise err class ImageMemberRepoProxy(glance.domain.proxy.Repo): def __init__(self, repo, image, context, store_api): self.repo = repo self.image = image self.context = context self.store_api = store_api super(ImageMemberRepoProxy, self).__init__(repo) def _set_acls(self): public = self.image.visibility == 'public' if self.image.locations and not public: member_ids = [m.member_id for m in self.repo.list()] for location in self.image.locations: self.store_api.set_acls(self.context, location['url'], public, read_tenants=member_ids) def add(self, member): super(ImageMemberRepoProxy, self).add(member) self._set_acls() def remove(self, member): super(ImageMemberRepoProxy, self).remove(member) self._set_acls() glance-2014.1/glance/notifier.py0000664000175400017540000003437112323736230017623 0ustar jenkinsjenkins00000000000000# Copyright 2011, OpenStack Foundation # Copyright 2012, Red Hat, Inc. # Copyright 2013 IBM Corp. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from oslo.config import cfg from oslo import messaging import webob from glance.common import exception import glance.domain.proxy import glance.openstack.common.log as logging from glance.openstack.common import timeutils notifier_opts = [ cfg.StrOpt('notifier_strategy', default='default', help=_('Notifications can be sent when images are create, ' 'updated or deleted. There are three methods of sending ' 'notifications, logging (via the log_file directive), ' 'rabbit (via a rabbitmq queue), qpid (via a Qpid ' 'message queue), or noop (no notifications sent, the ' 'default). (DEPRECATED)')), cfg.StrOpt('default_publisher_id', default="image.localhost", help='Default publisher_id for outgoing notifications.'), ] CONF = cfg.CONF CONF.register_opts(notifier_opts) LOG = logging.getLogger(__name__) _STRATEGY_ALIASES = { "logging": "log", "rabbit": "messaging", "qpid": "messaging", "noop": "noop", "default": "noop", } _ALIASES = { 'glance.openstack.common.rpc.impl_kombu': 'rabbit', 'glance.openstack.common.rpc.impl_qpid': 'qpid', 'glance.openstack.common.rpc.impl_zmq': 'zmq', } class Notifier(object): """Uses a notification strategy to send out messages about events.""" def __init__(self, strategy=None): _driver = None _strategy = strategy if CONF.notifier_strategy != 'default': msg = _("notifier_strategy was deprecated in " "favor of `notification_driver`") LOG.warn(msg) # NOTE(flaper87): Use this to keep backwards # compatibility. We'll try to get an oslo.messaging # driver from the specified strategy. _strategy = strategy or CONF.notifier_strategy _driver = _STRATEGY_ALIASES.get(_strategy) publisher_id = CONF.default_publisher_id try: # NOTE(flaper87): Assume the user has configured # the transport url. self._transport = messaging.get_transport(CONF, aliases=_ALIASES) except messaging.DriverLoadFailure: # NOTE(flaper87): Catch driver load failures and re-raise # them *just* if the `transport_url` option was set. This # step is intended to keep backwards compatibility and avoid # weird behaviors (like exceptions on missing dependencies) # when the old notifier options are used. if CONF.transport_url is not None: with excutils.save_and_reraise_exception(): LOG.exception(_('Error loading the notifier')) # NOTE(flaper87): This needs to be checked # here because the `get_transport` call # registers `transport_url` into ConfigOpts. if not CONF.transport_url: # NOTE(flaper87): The next 3 lines help # with the migration to oslo.messaging. # Without them, gate tests won't know # what driver should be loaded. # Once this patch lands, devstack will be # updated and then these lines will be removed. url = None if _strategy in ['rabbit', 'qpid']: url = _strategy + '://' self._transport = messaging.get_transport(CONF, url, aliases=_ALIASES) self._notifier = messaging.Notifier(self._transport, driver=_driver, publisher_id=publisher_id) def warn(self, event_type, payload): self._notifier.warn({}, event_type, payload) def info(self, event_type, payload): self._notifier.info({}, event_type, payload) def error(self, event_type, payload): self._notifier.error({}, event_type, payload) def format_image_notification(image): """ Given a glance.domain.Image object, return a dictionary of relevant notification information. We purposely do not include 'location' as it may contain credentials. """ return { 'id': image.image_id, 'name': image.name, 'status': image.status, 'created_at': timeutils.isotime(image.created_at), 'updated_at': timeutils.isotime(image.updated_at), 'min_disk': image.min_disk, 'min_ram': image.min_ram, 'protected': image.protected, 'checksum': image.checksum, 'owner': image.owner, 'disk_format': image.disk_format, 'container_format': image.container_format, 'size': image.size, 'is_public': image.visibility == 'public', 'properties': dict(image.extra_properties), 'tags': list(image.tags), 'deleted': False, 'deleted_at': None, } def format_task_notification(task): # NOTE(nikhil): input is not passed to the notifier payload as it may # contain sensitive info. return {'id': task.task_id, 'type': task.type, 'status': task.status, 'result': None, 'owner': task.owner, 'message': None, 'expires_at': timeutils.isotime(task.expires_at), 'created_at': timeutils.isotime(task.created_at), 'updated_at': timeutils.isotime(task.updated_at), 'deleted': False, 'deleted_at': None, } class ImageRepoProxy(glance.domain.proxy.Repo): def __init__(self, image_repo, context, notifier): self.image_repo = image_repo self.context = context self.notifier = notifier proxy_kwargs = {'context': self.context, 'notifier': self.notifier} super(ImageRepoProxy, self).__init__(image_repo, item_proxy_class=ImageProxy, item_proxy_kwargs=proxy_kwargs) def save(self, image): super(ImageRepoProxy, self).save(image) self.notifier.info('image.update', format_image_notification(image)) def add(self, image): super(ImageRepoProxy, self).add(image) self.notifier.info('image.create', format_image_notification(image)) def remove(self, image): super(ImageRepoProxy, self).remove(image) payload = format_image_notification(image) payload['deleted'] = True payload['deleted_at'] = timeutils.isotime() self.notifier.info('image.delete', payload) class ImageFactoryProxy(glance.domain.proxy.ImageFactory): def __init__(self, factory, context, notifier): kwargs = {'context': context, 'notifier': notifier} super(ImageFactoryProxy, self).__init__(factory, proxy_class=ImageProxy, proxy_kwargs=kwargs) class ImageProxy(glance.domain.proxy.Image): def __init__(self, image, context, notifier): self.image = image self.context = context self.notifier = notifier super(ImageProxy, self).__init__(image) def _format_image_send(self, bytes_sent): return { 'bytes_sent': bytes_sent, 'image_id': self.image.image_id, 'owner_id': self.image.owner, 'receiver_tenant_id': self.context.tenant, 'receiver_user_id': self.context.user, } def get_data(self): sent = 0 for chunk in self.image.get_data(): yield chunk sent += len(chunk) if sent != self.image.size: notify = self.notifier.error else: notify = self.notifier.info try: notify('image.send', self._format_image_send(sent)) except Exception as err: msg = (_("An error occurred during image.send" " notification: %(err)s") % {'err': err}) LOG.error(msg) def set_data(self, data, size=None): payload = format_image_notification(self.image) self.notifier.info('image.prepare', payload) try: self.image.set_data(data, size) except exception.StorageFull as e: msg = (_("Image storage media is full: %s") % e) self.notifier.error('image.upload', msg) raise webob.exc.HTTPRequestEntityTooLarge(explanation=msg) except exception.StorageWriteDenied as e: msg = (_("Insufficient permissions on image storage media: %s") % e) self.notifier.error('image.upload', msg) raise webob.exc.HTTPServiceUnavailable(explanation=msg) except ValueError as e: msg = (_("Cannot save data for image %(image_id)s: %(error)s") % {'image_id': self.image.image_id, 'error': e}) self.notifier.error('image.upload', msg) raise webob.exc.HTTPBadRequest(explanation=unicode(e)) except exception.Duplicate as e: msg = (_("Unable to upload duplicate image data for image" "%(image_id)s: %(error)s") % {'image_id': self.image.image_id, 'error': e}) self.notifier.error('image.upload', msg) raise webob.exc.HTTPConflict(explanation=msg) except exception.Forbidden as e: msg = (_("Not allowed to upload image data for image %(image_id)s:" " %(error)s") % {'image_id': self.image.image_id, 'error': e}) self.notifier.error('image.upload', msg) raise webob.exc.HTTPForbidden(explanation=msg) except exception.NotFound as e: msg = (_("Image %(image_id)s could not be found after upload." " The image may have been deleted during the upload:" " %(error)s") % {'image_id': self.image.image_id, 'error': e}) self.notifier.error('image.upload', msg) raise webob.exc.HTTPNotFound(explanation=unicode(e)) except webob.exc.HTTPError as e: msg = (_("Failed to upload image data for image %(image_id)s" " due to HTTP error: %(error)s") % {'image_id': self.image.image_id, 'error': e}) self.notifier.error('image.upload', msg) raise except Exception as e: msg = (_("Failed to upload image data for image %(image_id)s " "due to internal error: %(error)s") % {'image_id': self.image.image_id, 'error': e}) self.notifier.error('image.upload', msg) raise else: payload = format_image_notification(self.image) self.notifier.info('image.upload', payload) self.notifier.info('image.activate', payload) class TaskRepoProxy(glance.domain.proxy.TaskRepo): def __init__(self, task_repo, context, notifier): self.task_repo = task_repo self.context = context self.notifier = notifier proxy_kwargs = {'context': self.context, 'notifier': self.notifier} super(TaskRepoProxy, self) \ .__init__(task_repo, task_proxy_class=TaskProxy, task_proxy_kwargs=proxy_kwargs, task_details_proxy_class=TaskDetailsProxy, task_details_proxy_kwargs=proxy_kwargs) def add(self, task, task_details=None): self.notifier.info('task.create', format_task_notification(task)) super(TaskRepoProxy, self).add(task, task_details) def remove(self, task): payload = format_task_notification(task) payload['deleted'] = True payload['deleted_at'] = timeutils.isotime() self.notifier.info('task.delete', payload) super(TaskRepoProxy, self).remove(task) class TaskFactoryProxy(glance.domain.proxy.TaskFactory): def __init__(self, task_factory, context, notifier): kwargs = {'context': context, 'notifier': notifier} super(TaskFactoryProxy, self).__init__( task_factory, task_proxy_class=TaskProxy, task_proxy_kwargs=kwargs, task_details_proxy_class=TaskDetailsProxy, task_details_proxy_kwargs=kwargs) class TaskProxy(glance.domain.proxy.Task): def __init__(self, task, context, notifier): self.task = task self.context = context self.notifier = notifier super(TaskProxy, self).__init__(task) def run(self, executor): self.notifier.info('task.run', format_task_notification(self.task)) return super(TaskProxy, self).run(executor) def begin_processing(self): self.notifier.info( 'task.processing', format_task_notification(self.task) ) return super(TaskProxy, self).begin_processing() def succeed(self, result): self.notifier.info('task.success', format_task_notification(self.task)) return super(TaskProxy, self).succeed(result) def fail(self, message): self.notifier.info('task.failure', format_task_notification(self.task)) return super(TaskProxy, self).fail(message) class TaskDetailsProxy(glance.domain.proxy.TaskDetails): def __init__(self, task_details, context, notifier): self.task_details = task_details self.context = context self.notifier = notifier super(TaskDetailsProxy, self).__init__(task_details) glance-2014.1/glance/common/0000775000175400017540000000000012323736427016722 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/common/crypt.py0000664000175400017540000000423112323736226020432 0ustar jenkinsjenkins00000000000000#!/usr/bin/env python # Copyright 2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ Routines for URL-safe encrypting/decrypting """ import base64 from Crypto.Cipher import AES from Crypto import Random from Crypto.Random import random def urlsafe_encrypt(key, plaintext, blocksize=16): """ Encrypts plaintext. Resulting ciphertext will contain URL-safe characters :param key: AES secret key :param plaintext: Input text to be encrypted :param blocksize: Non-zero integer multiple of AES blocksize in bytes (16) :returns : Resulting ciphertext """ def pad(text): """ Pads text to be encrypted """ pad_length = (blocksize - len(text) % blocksize) sr = random.StrongRandom() pad = ''.join(chr(sr.randint(1, 0xFF)) for i in range(pad_length - 1)) # We use chr(0) as a delimiter between text and padding return text + chr(0) + pad # random initial 16 bytes for CBC init_vector = Random.get_random_bytes(16) cypher = AES.new(key, AES.MODE_CBC, init_vector) padded = cypher.encrypt(pad(str(plaintext))) return base64.urlsafe_b64encode(init_vector + padded) def urlsafe_decrypt(key, ciphertext): """ Decrypts URL-safe base64 encoded ciphertext :param key: AES secret key :param ciphertext: The encrypted text to decrypt :returns : Resulting plaintext """ # Cast from unicode ciphertext = base64.urlsafe_b64decode(str(ciphertext)) cypher = AES.new(key, AES.MODE_CBC, ciphertext[:16]) padded = cypher.decrypt(ciphertext[16:]) return padded[:padded.rfind(chr(0))] glance-2014.1/glance/common/rpc.py0000664000175400017540000002176712323736226020072 0ustar jenkinsjenkins00000000000000# Copyright 2013 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. """ RPC Controller """ import datetime import traceback from oslo.config import cfg import six from webob import exc from glance.common import client from glance.common import exception from glance.common import wsgi import glance.openstack.common.importutils as imp import glance.openstack.common.log as logging from glance.openstack.common import timeutils LOG = logging.getLogger(__name__) rpc_opts = [ # NOTE(flaper87): Shamelessly copied # from oslo rpc. cfg.ListOpt('allowed_rpc_exception_modules', default=['openstack.common.exception', 'glance.common.exception', 'exceptions', ], help='Modules of exceptions that are permitted to be recreated' 'upon receiving exception data from an rpc call.'), ] CONF = cfg.CONF CONF.register_opts(rpc_opts) class RPCJSONSerializer(wsgi.JSONResponseSerializer): def _sanitizer(self, obj): def to_primitive(_type, _value): return {"_type": _type, "_value": _value} if isinstance(obj, datetime.datetime): return to_primitive("datetime", timeutils.strtime(obj)) return super(RPCJSONSerializer, self)._sanitizer(obj) class RPCJSONDeserializer(wsgi.JSONRequestDeserializer): def _to_datetime(self, obj): return timeutils.parse_strtime(obj) def _sanitizer(self, obj): try: _type, _value = obj["_type"], obj["_value"] return getattr(self, "_to_" + _type)(_value) except (KeyError, AttributeError): return obj class Controller(object): """ Base RPCController. This is the base controller for RPC based APIs. Commands handled by this controller respect the following form: [{ 'command': 'method_name', 'kwargs': {...} }] The controller is capable of processing more than one command per request and will always return a list of results. :params raise_exc: Boolean that specifies whether to raise exceptions instead of "serializing" them. """ def __init__(self, raise_exc=False): self._registered = {} self.raise_exc = raise_exc def register(self, resource, filtered=None, excluded=None, refiner=None): """ Exports methods through the RPC Api. :params resource: Resource's instance to register. :params filtered: List of methods that *can* me registered. Read as "Method must be in this list". :params excluded: List of methods to exclude. :params refiner: Callable to use as filter for methods. :raises AssertionError: If refiner is not callable. """ funcs = filter(lambda x: not x.startswith("_"), dir(resource)) if filtered: funcs = [f for f in funcs if f in filtered] if excluded: funcs = [f for f in funcs if f not in excluded] if refiner: assert callable(refiner), "Refiner must be callable" funcs = filter(refiner, funcs) for name in funcs: meth = getattr(resource, name) if not callable(meth): continue self._registered[name] = meth def __call__(self, req, body): """ Executes the command """ if not isinstance(body, list): msg = _("Request must be a list of commands") raise exc.HTTPBadRequest(explanation=msg) def validate(cmd): if not isinstance(cmd, dict): msg = _("Bad Command: %s") % str(cmd) raise exc.HTTPBadRequest(explanation=msg) command, kwargs = cmd.get("command"), cmd.get("kwargs") if (not command or not isinstance(command, six.string_types) or (kwargs and not isinstance(kwargs, dict))): msg = _("Wrong command structure: %s") % (str(cmd)) raise exc.HTTPBadRequest(explanation=msg) method = self._registered.get(command) if not method: # Just raise 404 if the user tries to # access a private method. No need for # 403 here since logically the command # is not registered to the rpc dispatcher raise exc.HTTPNotFound(explanation=_("Command not found")) return True # If more than one command were sent then they might # be intended to be executed sequentially, that for, # lets first verify they're all valid before executing # them. commands = filter(validate, body) results = [] for cmd in commands: # kwargs is not required command, kwargs = cmd["command"], cmd.get("kwargs", {}) method = self._registered[command] try: result = method(req.context, **kwargs) except Exception as e: if self.raise_exc: raise cls, val = e.__class__, six.text_type(e) msg = (_("RPC Call Error: %(val)s\n%(tb)s") % dict(val=val, tb=traceback.format_exc())) LOG.error(msg) # NOTE(flaper87): Don't propagate all exceptions # but the ones allowed by the user. module = cls.__module__ if module not in CONF.allowed_rpc_exception_modules: cls = exception.RPCError val = six.text_type(exception.RPCError(cls=cls, val=val)) cls_path = "%s.%s" % (cls.__module__, cls.__name__) result = {"_error": {"cls": cls_path, "val": val}} results.append(result) return results class RPCClient(client.BaseClient): def __init__(self, *args, **kwargs): self._serializer = RPCJSONSerializer() self._deserializer = RPCJSONDeserializer() self.raise_exc = kwargs.pop("raise_exc", True) self.base_path = kwargs.pop("base_path", '/rpc') super(RPCClient, self).__init__(*args, **kwargs) @client.handle_unauthenticated def bulk_request(self, commands): """ Execute multiple commands in a single request. :params commands: List of commands to send. Commands must respect the following form: { 'command': 'method_name', 'kwargs': method_kwargs } """ body = self._serializer.to_json(commands) response = super(RPCClient, self).do_request('POST', self.base_path, body) return self._deserializer.from_json(response.read()) def do_request(self, method, **kwargs): """ Simple do_request override. This method serializes the outgoing body and builds the command that will be sent. :params method: The remote python method to call :params kwargs: Dynamic parameters that will be passed to the remote method. """ content = self.bulk_request([{'command': method, 'kwargs': kwargs}]) # NOTE(flaper87): Return the first result if # a single command was executed. content = content[0] # NOTE(flaper87): Check if content is an error # and re-raise it if raise_exc is True. Before # checking if content contains the '_error' key, # verify if it is an instance of dict - since the # RPC call may have returned something different. if self.raise_exc and (isinstance(content, dict) and '_error' in content): error = content['_error'] try: exc_cls = imp.import_class(error['cls']) raise exc_cls(error['val']) except ImportError: # NOTE(flaper87): The exception # class couldn't be imported, using # a generic exception. raise exception.RPCError(**error) return content def __getattr__(self, item): """ This method returns a method_proxy that will execute the rpc call in the registry service. """ if item.startswith('_'): raise AttributeError(item) def method_proxy(**kw): return self.do_request(item, **kw) return method_proxy glance-2014.1/glance/common/wsgi.py0000664000175400017540000006013212323736226020244 0ustar jenkinsjenkins00000000000000# Copyright 2010 United States Government as represented by the # Administrator of the National Aeronautics and Space Administration. # Copyright 2010 OpenStack Foundation # Copyright 2014 IBM Corp. # 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. """ Utility methods for working with WSGI servers """ from __future__ import print_function import datetime import errno import json import os import signal import sys import time import eventlet from eventlet.green import socket from eventlet.green import ssl import eventlet.greenio import eventlet.wsgi from oslo.config import cfg import routes import routes.middleware import webob.dec import webob.exc from webob import multidict from glance.common import exception from glance.common import utils from glance.openstack.common import gettextutils from glance.openstack.common import jsonutils import glance.openstack.common.log as logging bind_opts = [ cfg.StrOpt('bind_host', default='0.0.0.0', help=_('Address to bind the server. Useful when ' 'selecting a particular network interface.')), cfg.IntOpt('bind_port', help=_('The port on which the server will listen.')), ] socket_opts = [ cfg.IntOpt('backlog', default=4096, help=_('The backlog value that will be used when creating the ' 'TCP listener socket.')), cfg.IntOpt('tcp_keepidle', default=600, help=_('The value for the socket option TCP_KEEPIDLE. This is ' 'the time in seconds that the connection must be idle ' 'before TCP starts sending keepalive probes.')), cfg.StrOpt('ca_file', help=_('CA certificate file to use to verify ' 'connecting clients.')), cfg.StrOpt('cert_file', help=_('Certificate file to use when starting API ' 'server securely.')), cfg.StrOpt('key_file', help=_('Private key file to use when starting API ' 'server securely.')), ] eventlet_opts = [ cfg.IntOpt('workers', default=1, help=_('The number of child process workers that will be ' 'created to service API requests.')), cfg.StrOpt('eventlet_hub', default='poll', help=_('Name of eventlet hub to use. Traditionally, we have ' 'only supported \'poll\', however \'selects\' may be ' 'appropriate for some platforms. See ' 'http://eventlet.net/doc/hubs.html for more details.')), cfg.IntOpt('max_header_line', default=16384, help=_('Maximum line size of message headers to be accepted. ' 'max_header_line may need to be increased when using ' 'large tokens (typically those generated by the ' 'Keystone v3 API with big service catalogs')), ] CONF = cfg.CONF CONF.register_opts(bind_opts) CONF.register_opts(socket_opts) CONF.register_opts(eventlet_opts) def get_bind_addr(default_port=None): """Return the host and port to bind to.""" return (CONF.bind_host, CONF.bind_port or default_port) def get_socket(default_port): """ Bind socket to bind ip:port in conf note: Mostly comes from Swift with a few small changes... :param default_port: port to bind to if none is specified in conf :returns : a socket object as returned from socket.listen or ssl.wrap_socket if conf specifies cert_file """ bind_addr = get_bind_addr(default_port) # TODO(jaypipes): eventlet's greened socket module does not actually # support IPv6 in getaddrinfo(). We need to get around this in the # future or monitor upstream for a fix address_family = [ addr[0] for addr in socket.getaddrinfo(bind_addr[0], bind_addr[1], socket.AF_UNSPEC, socket.SOCK_STREAM) if addr[0] in (socket.AF_INET, socket.AF_INET6) ][0] cert_file = CONF.cert_file key_file = CONF.key_file use_ssl = cert_file or key_file if use_ssl and (not cert_file or not key_file): raise RuntimeError(_("When running server in SSL mode, you must " "specify both a cert_file and key_file " "option value in your configuration file")) def wrap_ssl(sock): utils.validate_key_cert(key_file, cert_file) ssl_kwargs = { 'server_side': True, 'certfile': cert_file, 'keyfile': key_file, 'cert_reqs': ssl.CERT_NONE, } if CONF.ca_file: ssl_kwargs['ca_certs'] = CONF.ca_file ssl_kwargs['cert_reqs'] = ssl.CERT_REQUIRED return ssl.wrap_socket(sock, **ssl_kwargs) sock = utils.get_test_suite_socket() retry_until = time.time() + 30 if sock and use_ssl: sock = wrap_ssl(sock) while not sock and time.time() < retry_until: try: sock = eventlet.listen(bind_addr, backlog=CONF.backlog, family=address_family) if use_ssl: sock = wrap_ssl(sock) except socket.error as err: if err.args[0] != errno.EADDRINUSE: raise eventlet.sleep(0.1) if not sock: raise RuntimeError(_("Could not bind to %(host)s:%(port)s after" " trying for 30 seconds") % {'host': bind_addr[0], 'port': bind_addr[1]}) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # in my experience, sockets can hang around forever without keepalive sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) # This option isn't available in the OS X version of eventlet if hasattr(socket, 'TCP_KEEPIDLE'): sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, CONF.tcp_keepidle) return sock class Server(object): """Server class to manage multiple WSGI sockets and applications.""" def __init__(self, threads=1000): eventlet.wsgi.MAX_HEADER_LINE = CONF.max_header_line self.threads = threads self.children = [] self.running = True def start(self, application, default_port): """ Run a WSGI server with the given application. :param application: The application to be run in the WSGI server :param default_port: Port to bind to if none is specified in conf """ pgid = os.getpid() try: # NOTE(flaper87): Make sure this process # runs in its own process group. os.setpgid(pgid, pgid) except OSError: # NOTE(flaper87): When running glance-control, # (glance's functional tests, for example) # setpgid fails with EPERM as glance-control # creates a fresh session, of which the newly # launched service becomes the leader (session # leaders may not change process groups) # # Running glance-(api|registry) is safe and # shouldn't raise any error here. pgid = 0 def kill_children(*args): """Kills the entire process group.""" signal.signal(signal.SIGTERM, signal.SIG_IGN) signal.signal(signal.SIGINT, signal.SIG_IGN) self.running = False os.killpg(pgid, signal.SIGTERM) def hup(*args): """ Shuts down the server, but allows running requests to complete """ signal.signal(signal.SIGHUP, signal.SIG_IGN) self.running = False self.application = application self.sock = get_socket(default_port) os.umask(0o27) # ensure files are created with the correct privileges self.logger = logging.getLogger('glance.wsgi.server') if CONF.workers == 0: # Useful for profiling, test, debug etc. self.pool = self.create_pool() self.pool.spawn_n(self._single_run, self.application, self.sock) return else: self.logger.info(_("Starting %d workers") % CONF.workers) signal.signal(signal.SIGTERM, kill_children) signal.signal(signal.SIGINT, kill_children) signal.signal(signal.SIGHUP, hup) while len(self.children) < CONF.workers: self.run_child() def create_pool(self): return eventlet.GreenPool(size=self.threads) def wait_on_children(self): while self.running: try: pid, status = os.wait() if os.WIFEXITED(status) or os.WIFSIGNALED(status): self.logger.info(_('Removing dead child %s') % pid) self.children.remove(pid) if os.WIFEXITED(status) and os.WEXITSTATUS(status) != 0: self.logger.error(_('Not respawning child %d, cannot ' 'recover from termination') % pid) if not self.children: self.logger.info( _('All workers have terminated. Exiting')) self.running = False else: self.run_child() except OSError as err: if err.errno not in (errno.EINTR, errno.ECHILD): raise except KeyboardInterrupt: self.logger.info(_('Caught keyboard interrupt. Exiting.')) break eventlet.greenio.shutdown_safe(self.sock) self.sock.close() self.logger.debug(_('Exited')) def wait(self): """Wait until all servers have completed running.""" try: if self.children: self.wait_on_children() else: self.pool.waitall() except KeyboardInterrupt: pass def run_child(self): pid = os.fork() if pid == 0: signal.signal(signal.SIGHUP, signal.SIG_DFL) signal.signal(signal.SIGTERM, signal.SIG_DFL) # ignore the interrupt signal to avoid a race whereby # a child worker receives the signal before the parent # and is respawned unnecessarily as a result signal.signal(signal.SIGINT, signal.SIG_IGN) self.run_server() self.logger.info(_('Child %d exiting normally') % os.getpid()) # self.pool.waitall() has been called by run_server, so # its safe to exit here sys.exit(0) else: self.logger.info(_('Started child %s') % pid) self.children.append(pid) def run_server(self): """Run a WSGI server.""" if cfg.CONF.pydev_worker_debug_host: utils.setup_remote_pydev_debug(cfg.CONF.pydev_worker_debug_host, cfg.CONF.pydev_worker_debug_port) eventlet.wsgi.HttpProtocol.default_request_version = "HTTP/1.0" try: eventlet.hubs.use_hub(cfg.CONF.eventlet_hub) except Exception: msg = _("eventlet '%s' hub is not available on this platform") raise exception.WorkerCreationFailure( reason=msg % cfg.CONF.eventlet_hub) self.pool = self.create_pool() try: eventlet.wsgi.server(self.sock, self.application, log=logging.WritableLogger(self.logger), custom_pool=self.pool, debug=False) except socket.error as err: if err[0] != errno.EINVAL: raise self.pool.waitall() def _single_run(self, application, sock): """Start a WSGI server in a new green thread.""" self.logger.info(_("Starting single process server")) eventlet.wsgi.server(sock, application, custom_pool=self.pool, log=logging.WritableLogger(self.logger), debug=False) class Middleware(object): """ Base WSGI middleware wrapper. These classes require an application to be initialized that will be called next. By default the middleware will simply call its wrapped app, or you can override __call__ to customize its behavior. """ def __init__(self, application): self.application = application @classmethod def factory(cls, global_conf, **local_conf): def filter(app): return cls(app) return filter def process_request(self, req): """ Called on each request. If this returns None, the next application down the stack will be executed. If it returns a response then that response will be returned and execution will stop here. """ return None def process_response(self, response): """Do whatever you'd like to the response.""" return response @webob.dec.wsgify def __call__(self, req): response = self.process_request(req) if response: return response response = req.get_response(self.application) response.request = req try: return self.process_response(response) except webob.exc.HTTPException as e: return e class Debug(Middleware): """ Helper class that can be inserted into any WSGI application chain to get information about the request and response. """ @webob.dec.wsgify def __call__(self, req): print(("*" * 40) + " REQUEST ENVIRON") for key, value in req.environ.items(): print(key, "=", value) print('') resp = req.get_response(self.application) print(("*" * 40) + " RESPONSE HEADERS") for (key, value) in resp.headers.iteritems(): print(key, "=", value) print('') resp.app_iter = self.print_generator(resp.app_iter) return resp @staticmethod def print_generator(app_iter): """ Iterator that prints the contents of a wrapper string iterator when iterated. """ print(("*" * 40) + " BODY") for part in app_iter: sys.stdout.write(part) sys.stdout.flush() yield part print class APIMapper(routes.Mapper): """ Handle route matching when url is '' because routes.Mapper returns an error in this case. """ def routematch(self, url=None, environ=None): if url is "": result = self._match("", environ) return result[0], result[1] return routes.Mapper.routematch(self, url, environ) class Router(object): """ WSGI middleware that maps incoming requests to WSGI apps. """ def __init__(self, mapper): """ Create a router for the given routes.Mapper. Each route in `mapper` must specify a 'controller', which is a WSGI app to call. You'll probably want to specify an 'action' as well and have your controller be a wsgi.Controller, who will route the request to the action method. Examples: mapper = routes.Mapper() sc = ServerController() # Explicit mapping of one route to a controller+action mapper.connect(None, "/svrlist", controller=sc, action="list") # Actions are all implicitly defined mapper.resource("server", "servers", controller=sc) # Pointing to an arbitrary WSGI app. You can specify the # {path_info:.*} parameter so the target app can be handed just that # section of the URL. mapper.connect(None, "/v1.0/{path_info:.*}", controller=BlogApp()) """ mapper.redirect("", "/") self.map = mapper self._router = routes.middleware.RoutesMiddleware(self._dispatch, self.map) @classmethod def factory(cls, global_conf, **local_conf): return cls(APIMapper()) @webob.dec.wsgify def __call__(self, req): """ Route the incoming request to a controller based on self.map. If no match, return a 404. """ return self._router @staticmethod @webob.dec.wsgify def _dispatch(req): """ Called by self._router after matching the incoming request to a route and putting the information into req.environ. Either returns 404 or the routed WSGI app's response. """ match = req.environ['wsgiorg.routing_args'][1] if not match: return webob.exc.HTTPNotFound() app = match['controller'] return app class Request(webob.Request): """Add some OpenStack API-specific logic to the base webob.Request.""" def best_match_content_type(self): """Determine the requested response content-type.""" supported = ('application/json',) bm = self.accept.best_match(supported) return bm or 'application/json' def get_content_type(self, allowed_content_types): """Determine content type of the request body.""" if "Content-Type" not in self.headers: raise exception.InvalidContentType(content_type=None) content_type = self.content_type if content_type not in allowed_content_types: raise exception.InvalidContentType(content_type=content_type) else: return content_type def best_match_language(self): """Determines best available locale from the Accept-Language header. :returns: the best language match or None if the 'Accept-Language' header was not available in the request. """ if not self.accept_language: return None langs = gettextutils.get_available_languages('glance') return self.accept_language.best_match(langs) class JSONRequestDeserializer(object): def has_body(self, request): """ Returns whether a Webob.Request object will possess an entity body. :param request: Webob.Request object """ if 'transfer-encoding' in request.headers: return True elif request.content_length > 0: return True return False def _sanitizer(self, obj): """Sanitizer method that will be passed to jsonutils.loads.""" return obj def from_json(self, datastring): try: return json.loads(datastring, object_hook=self._sanitizer) except ValueError: msg = _('Malformed JSON in request body.') raise webob.exc.HTTPBadRequest(explanation=msg) def default(self, request): if self.has_body(request): return {'body': self.from_json(request.body)} else: return {} class JSONResponseSerializer(object): def _sanitizer(self, obj): """Sanitizer method that will be passed to jsonutils.dumps.""" if isinstance(obj, datetime.datetime): return obj.isoformat() if hasattr(obj, "to_dict"): return obj.to_dict() if isinstance(obj, multidict.MultiDict): return obj.mixed() if isinstance(obj, set): return list(obj) return obj def to_json(self, data): return jsonutils.dumps(data, default=self._sanitizer) def default(self, response, result): response.content_type = 'application/json' response.body = self.to_json(result) def translate_exception(req, e): """Translates all translatable elements of the given exception.""" # The RequestClass attribute in the webob.dec.wsgify decorator # does not guarantee that the request object will be a particular # type; this check is therefore necessary. if not hasattr(req, "best_match_language"): return e locale = req.best_match_language() if isinstance(e, webob.exc.HTTPError): e.explanation = gettextutils.translate(e.explanation, locale) e.detail = gettextutils.translate(e.detail, locale) if getattr(e, 'body_template', None): e.body_template = gettextutils.translate(e.body_template, locale) return e class Resource(object): """ WSGI app that handles (de)serialization and controller dispatch. Reads routing information supplied by RoutesMiddleware and calls the requested action method upon its deserializer, controller, and serializer. Those three objects may implement any of the basic controller action methods (create, update, show, index, delete) along with any that may be specified in the api router. A 'default' method may also be implemented to be used in place of any non-implemented actions. Deserializer methods must accept a request argument and return a dictionary. Controller methods must accept a request argument. Additionally, they must also accept keyword arguments that represent the keys returned by the Deserializer. They may raise a webob.exc exception or return a dict, which will be serialized by requested content type. """ def __init__(self, controller, deserializer=None, serializer=None): """ :param controller: object that implement methods created by routes lib :param deserializer: object that supports webob request deserialization through controller-like actions :param serializer: object that supports webob response serialization through controller-like actions """ self.controller = controller self.serializer = serializer or JSONResponseSerializer() self.deserializer = deserializer or JSONRequestDeserializer() @webob.dec.wsgify(RequestClass=Request) def __call__(self, request): """WSGI method that controls (de)serialization and method dispatch.""" action_args = self.get_action_args(request.environ) action = action_args.pop('action', None) try: deserialized_request = self.dispatch(self.deserializer, action, request) action_args.update(deserialized_request) action_result = self.dispatch(self.controller, action, request, **action_args) except webob.exc.WSGIHTTPException as e: exc_info = sys.exc_info() raise translate_exception(request, e), None, exc_info[2] try: response = webob.Response(request=request) self.dispatch(self.serializer, action, response, action_result) return response except webob.exc.WSGIHTTPException as e: return translate_exception(request, e) except webob.exc.HTTPException as e: return e # return unserializable result (typically a webob exc) except Exception: return action_result def dispatch(self, obj, action, *args, **kwargs): """Find action-specific method on self and call it.""" try: method = getattr(obj, action) except AttributeError: method = getattr(obj, 'default') return method(*args, **kwargs) def get_action_args(self, request_environment): """Parse dictionary created by routes library.""" try: args = request_environment['wsgiorg.routing_args'][1].copy() except Exception: return {} try: del args['controller'] except KeyError: pass try: del args['format'] except KeyError: pass return args glance-2014.1/glance/common/location_strategy/0000775000175400017540000000000012323736427022454 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/common/location_strategy/store_type.py0000664000175400017540000001015112323736226025216 0ustar jenkinsjenkins00000000000000# Copyright 2014 IBM Corp. # 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. """Storage preference based location strategy module""" from oslo.config import cfg import six import six.moves.urllib.parse as urlparse store_type_opts = [ cfg.ListOpt("store_type_preference", default=[], help=_("The store names to use to get store preference order. " "The name must be registered by one of the stores " "defined by the 'known_stores' config option. " "This option will be applied when you using " "'store_type' option as image location strategy " "defined by the 'location_strategy' config option.")) ] CONF = cfg.CONF CONF.register_opts(store_type_opts, group='store_type_location_strategy') _STORE_TO_SCHEME_MAP = {} def get_strategy_name(): """Return strategy module name.""" return 'store_type' def init(): """Initialize strategy module.""" # NOTE(zhiyan): We have a plan to do a reusable glance client library for # all clients like Nova and Cinder in near period, it would be able to # contains common code to provide uniform image service interface for them, # just like Brick in Cinder, this code can be moved to there and shared # between Glance and client both side. So this implementation as far as # possible to prevent make relationships with Glance(server)-specific code, # for example: using functions within store module to validate # 'store_type_preference' option. mapping = {'filesystem': ['file', 'filesystem'], 'http': ['http', 'https'], 'rbd': ['rbd'], 's3': ['s3', 's3+http', 's3+https'], 'swift': ['swift', 'swift+https', 'swift+http'], 'gridfs': ['gridfs'], 'sheepdog': ['sheepdog'], 'cinder': ['cinder'], 'vmware_datastore': ['vsphere']} _STORE_TO_SCHEME_MAP.clear() _STORE_TO_SCHEME_MAP.update(mapping) def get_ordered_locations(locations, uri_key='url', **kwargs): """ Order image location list. :param locations: The original image location list. :param uri_key: The key name for location URI in image location dictionary. :return: The image location list with preferred store type order. """ def _foreach_store_type_preference(): store_types = CONF.store_type_location_strategy.store_type_preference for preferred_store in store_types: preferred_store = str(preferred_store).strip() if not preferred_store: continue yield preferred_store if not locations: return locations preferences = {} others = [] for preferred_store in _foreach_store_type_preference(): preferences[preferred_store] = [] for location in locations: uri = location.get(uri_key) if not uri: continue pieces = urlparse.urlparse(uri.strip()) store_name = None for store, schemes in six.iteritems(_STORE_TO_SCHEME_MAP): if pieces.scheme.strip() in schemes: store_name = store break if store_name in preferences: preferences[store_name].append(location) else: others.append(location) ret = [] # NOTE(zhiyan): While configuration again since py26 does not support # ordereddict container. for preferred_store in _foreach_store_type_preference(): ret.extend(preferences[preferred_store]) ret.extend(others) return ret glance-2014.1/glance/common/location_strategy/location_order.py0000664000175400017540000000206712323736226026033 0ustar jenkinsjenkins00000000000000# Copyright 2014 IBM Corp. # 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 location order based location strategy module""" def get_strategy_name(): """Return strategy module name.""" return 'location_order' def init(): """Initialize strategy module.""" pass def get_ordered_locations(locations, **kwargs): """ Order image location list. :param locations: The original image location list. :return: The image location list with original natural order. """ return locations glance-2014.1/glance/common/location_strategy/__init__.py0000664000175400017540000000747112323736226024573 0ustar jenkinsjenkins00000000000000# Copyright 2014 IBM Corp. # 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 copy from oslo.config import cfg import stevedore import glance.openstack.common.log as logging location_strategy_opts = [ cfg.StrOpt('location_strategy', default='location_order', help=_("This value sets what strategy will be used to " "determine the image location order. Currently " "two strategies are packaged with Glance " "'location_order' and 'store_type'.")) ] CONF = cfg.CONF CONF.register_opts(location_strategy_opts) LOG = logging.getLogger(__name__) def _load_strategies(): """Load all strategy modules.""" modules = {} namespace = "glance.common.image_location_strategy.modules" ex = stevedore.extension.ExtensionManager(namespace) for module_name in ex.names(): try: mgr = stevedore.driver.DriverManager( namespace=namespace, name=module_name, invoke_on_load=False) # Obtain module name strategy_name = str(mgr.driver.get_strategy_name()) if strategy_name in modules: msg = (_('%(strategy)s is registered as a module twice. ' '%(module)s is not being used.') % {'strategy': strategy_name, 'module': module_name}) LOG.warn(msg) else: # Initialize strategy module mgr.driver.init() modules[strategy_name] = mgr.driver except Exception as e: LOG.error(_("Failed to load location strategy module " "%(module)s: %(e)s") % {'module': module_name, 'e': e}) return modules _available_strategies = _load_strategies() def verify_location_strategy(conf=None, strategies=_available_strategies): """Validate user configured 'location_strategy' option value.""" if not conf: conf = CONF.location_strategy if conf not in strategies: msg = (_('Invalid location_strategy option: %(name)s. ' 'The valid strategy option(s) is(are): %(strategies)s') % {'name': conf, 'strategies': ", ".join(strategies.keys())}) LOG.error(msg) raise RuntimeError(msg) def get_ordered_locations(locations, **kwargs): """ Order image location list by configured strategy. :param locations: The original image location list. :param kwargs: Strategy-specific arguments for under layer strategy module. :return: The image location list with strategy-specific order. """ if not locations: return [] strategy_module = _available_strategies[CONF.location_strategy] return strategy_module.get_ordered_locations(copy.deepcopy(locations), **kwargs) def choose_best_location(locations, **kwargs): """ Choose best location from image location list by configured strategy. :param locations: The original image location list. :param kwargs: Strategy-specific arguments for under layer strategy module. :return: The best location from image location list. """ locations = get_ordered_locations(locations, **kwargs) if locations: return locations[0] else: return None glance-2014.1/glance/common/utils.py0000664000175400017540000004370012323736230020430 0ustar jenkinsjenkins00000000000000# Copyright 2010 United States Government as represented by the # Administrator of the National Aeronautics and Space Administration. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ System-level utilities and helper functions. """ import errno try: from eventlet import sleep except ImportError: from time import sleep from eventlet.green import socket import functools import os import platform import subprocess import sys import uuid from OpenSSL import crypto from oslo.config import cfg from webob import exc from glance.common import exception import glance.openstack.common.log as logging from glance.openstack.common import strutils CONF = cfg.CONF LOG = logging.getLogger(__name__) FEATURE_BLACKLIST = ['content-length', 'content-type', 'x-image-meta-size'] # Whitelist of v1 API headers of form x-image-meta-xxx IMAGE_META_HEADERS = ['x-image-meta-location', 'x-image-meta-size', 'x-image-meta-is_public', 'x-image-meta-disk_format', 'x-image-meta-container_format', 'x-image-meta-name', 'x-image-meta-status', 'x-image-meta-copy_from', 'x-image-meta-uri', 'x-image-meta-checksum', 'x-image-meta-created_at', 'x-image-meta-updated_at', 'x-image-meta-deleted_at', 'x-image-meta-min_ram', 'x-image-meta-min_disk', 'x-image-meta-owner', 'x-image-meta-store', 'x-image-meta-id', 'x-image-meta-protected', 'x-image-meta-deleted'] GLANCE_TEST_SOCKET_FD_STR = 'GLANCE_TEST_SOCKET_FD' def chunkreadable(iter, chunk_size=65536): """ Wrap a readable iterator with a reader yielding chunks of a preferred size, otherwise leave iterator unchanged. :param iter: an iter which may also be readable :param chunk_size: maximum size of chunk """ return chunkiter(iter, chunk_size) if hasattr(iter, 'read') else iter def chunkiter(fp, chunk_size=65536): """ Return an iterator to a file-like obj which yields fixed size chunks :param fp: a file-like object :param chunk_size: maximum size of chunk """ while True: chunk = fp.read(chunk_size) if chunk: yield chunk else: break def cooperative_iter(iter): """ Return an iterator which schedules after each iteration. This can prevent eventlet thread starvation. :param iter: an iterator to wrap """ try: for chunk in iter: sleep(0) yield chunk except Exception as err: msg = _("Error: cooperative_iter exception %s") % err LOG.error(msg) raise def cooperative_read(fd): """ Wrap a file descriptor's read with a partial function which schedules after each read. This can prevent eventlet thread starvation. :param fd: a file descriptor to wrap """ def readfn(*args): result = fd.read(*args) sleep(0) return result return readfn class CooperativeReader(object): """ An eventlet thread friendly class for reading in image data. When accessing data either through the iterator or the read method we perform a sleep to allow a co-operative yield. When there is more than one image being uploaded/downloaded this prevents eventlet thread starvation, ie allows all threads to be scheduled periodically rather than having the same thread be continuously active. """ def __init__(self, fd): """ :param fd: Underlying image file object """ self.fd = fd self.iterator = None # NOTE(markwash): if the underlying supports read(), overwrite the # default iterator-based implementation with cooperative_read which # is more straightforward if hasattr(fd, 'read'): self.read = cooperative_read(fd) def read(self, length=None): """Return the next chunk of the underlying iterator. This is replaced with cooperative_read in __init__ if the underlying fd already supports read(). """ if self.iterator is None: self.iterator = self.__iter__() try: return self.iterator.next() except StopIteration: return '' def __iter__(self): return cooperative_iter(self.fd.__iter__()) class LimitingReader(object): """ Reader designed to fail when reading image data past the configured allowable amount. """ def __init__(self, data, limit): """ :param data: Underlying image data object :param limit: maximum number of bytes the reader should allow """ self.data = data self.limit = limit self.bytes_read = 0 def __iter__(self): for chunk in self.data: self.bytes_read += len(chunk) if self.bytes_read > self.limit: raise exception.ImageSizeLimitExceeded() else: yield chunk def read(self, i): result = self.data.read(i) self.bytes_read += len(result) if self.bytes_read > self.limit: raise exception.ImageSizeLimitExceeded() return result def image_meta_to_http_headers(image_meta): """ Returns a set of image metadata into a dict of HTTP headers that can be fed to either a Webob Request object or an httplib.HTTP(S)Connection object :param image_meta: Mapping of image metadata """ headers = {} for k, v in image_meta.items(): if v is not None: if k == 'properties': for pk, pv in v.items(): if pv is not None: headers["x-image-meta-property-%s" % pk.lower()] = unicode(pv) else: headers["x-image-meta-%s" % k.lower()] = unicode(v) return headers def add_features_to_http_headers(features, headers): """ Adds additional headers representing glance features to be enabled. :param headers: Base set of headers :param features: Map of enabled features """ if features: for k, v in features.items(): if k.lower() in FEATURE_BLACKLIST: raise exception.UnsupportedHeaderFeature(feature=k) if v is not None: headers[k.lower()] = unicode(v) def get_image_meta_from_headers(response): """ Processes HTTP headers from a supplied response that match the x-image-meta and x-image-meta-property and returns a mapping of image metadata and properties :param response: Response to process """ result = {} properties = {} if hasattr(response, 'getheaders'): # httplib.HTTPResponse headers = response.getheaders() else: # webob.Response headers = response.headers.items() for key, value in headers: key = str(key.lower()) if key.startswith('x-image-meta-property-'): field_name = key[len('x-image-meta-property-'):].replace('-', '_') properties[field_name] = value or None elif key.startswith('x-image-meta-'): field_name = key[len('x-image-meta-'):].replace('-', '_') if 'x-image-meta-' + field_name not in IMAGE_META_HEADERS: msg = _("Bad header: %(header_name)s") % {'header_name': key} raise exc.HTTPBadRequest(msg, content_type="text/plain") result[field_name] = value or None result['properties'] = properties for key in ('size', 'min_disk', 'min_ram'): if key in result: try: result[key] = int(result[key]) except ValueError: extra = (_("Cannot convert image %(key)s '%(value)s' " "to an integer.") % {'key': key, 'value': result[key]}) raise exception.InvalidParameterValue(value=result[key], param=key, extra_msg=extra) if result[key] < 0: extra = (_("Image %(key)s must be >= 0 " "('%(value)s' specified).") % {'key': key, 'value': result[key]}) raise exception.InvalidParameterValue(value=result[key], param=key, extra_msg=extra) for key in ('is_public', 'deleted', 'protected'): if key in result: result[key] = strutils.bool_from_string(result[key]) return result def safe_mkdirs(path): try: os.makedirs(path) except OSError as e: if e.errno != errno.EEXIST: raise def safe_remove(path): try: os.remove(path) except OSError as e: if e.errno != errno.ENOENT: raise class PrettyTable(object): """Creates an ASCII art table for use in bin/glance Example: ID Name Size Hits --- ----------------- ------------ ----- 122 image 22 0 """ def __init__(self): self.columns = [] def add_column(self, width, label="", just='l'): """Add a column to the table :param width: number of characters wide the column should be :param label: column heading :param just: justification for the column, 'l' for left, 'r' for right """ self.columns.append((width, label, just)) def make_header(self): label_parts = [] break_parts = [] for width, label, _ in self.columns: # NOTE(sirp): headers are always left justified label_part = self._clip_and_justify(label, width, 'l') label_parts.append(label_part) break_part = '-' * width break_parts.append(break_part) label_line = ' '.join(label_parts) break_line = ' '.join(break_parts) return '\n'.join([label_line, break_line]) def make_row(self, *args): row = args row_parts = [] for data, (width, _, just) in zip(row, self.columns): row_part = self._clip_and_justify(data, width, just) row_parts.append(row_part) row_line = ' '.join(row_parts) return row_line @staticmethod def _clip_and_justify(data, width, just): # clip field to column width clipped_data = str(data)[:width] if just == 'r': # right justify justified = clipped_data.rjust(width) else: # left justify justified = clipped_data.ljust(width) return justified def get_terminal_size(): def _get_terminal_size_posix(): import fcntl import struct import termios height_width = None try: height_width = struct.unpack('hh', fcntl.ioctl(sys.stderr.fileno(), termios.TIOCGWINSZ, struct.pack('HH', 0, 0))) except Exception: pass if not height_width: try: p = subprocess.Popen(['stty', 'size'], shell=False, stdout=subprocess.PIPE, stderr=open(os.devnull, 'w')) result = p.communicate() if p.returncode == 0: return tuple(int(x) for x in result[0].split()) except Exception: pass return height_width def _get_terminal_size_win32(): try: from ctypes import create_string_buffer from ctypes import windll handle = windll.kernel32.GetStdHandle(-12) csbi = create_string_buffer(22) res = windll.kernel32.GetConsoleScreenBufferInfo(handle, csbi) except Exception: return None if res: import struct unpack_tmp = struct.unpack("hhhhHhhhhhh", csbi.raw) (bufx, bufy, curx, cury, wattr, left, top, right, bottom, maxx, maxy) = unpack_tmp height = bottom - top + 1 width = right - left + 1 return (height, width) else: return None def _get_terminal_size_unknownOS(): raise NotImplementedError func = {'posix': _get_terminal_size_posix, 'win32': _get_terminal_size_win32} height_width = func.get(platform.os.name, _get_terminal_size_unknownOS)() if height_width is None: raise exception.Invalid() for i in height_width: if not isinstance(i, int) or i <= 0: raise exception.Invalid() return height_width[0], height_width[1] def mutating(func): """Decorator to enforce read-only logic""" @functools.wraps(func) def wrapped(self, req, *args, **kwargs): if req.context.read_only: msg = _("Read-only access") LOG.debug(msg) raise exc.HTTPForbidden(msg, request=req, content_type="text/plain") return func(self, req, *args, **kwargs) return wrapped def setup_remote_pydev_debug(host, port): error_msg = ('Error setting up the debug environment. Verify that the' ' option pydev_worker_debug_port is pointing to a valid ' 'hostname or IP on which a pydev server is listening on' ' the port indicated by pydev_worker_debug_port.') try: try: from pydev import pydevd except ImportError: import pydevd pydevd.settrace(host, port=port, stdoutToServer=True, stderrToServer=True) return True except Exception: LOG.exception(error_msg) raise class LazyPluggable(object): """A pluggable backend loaded lazily based on some value.""" def __init__(self, pivot, config_group=None, **backends): self.__backends = backends self.__pivot = pivot self.__backend = None self.__config_group = config_group def __get_backend(self): if not self.__backend: if self.__config_group is None: backend_name = CONF[self.__pivot] else: backend_name = CONF[self.__config_group][self.__pivot] if backend_name not in self.__backends: msg = _('Invalid backend: %s') % backend_name raise exception.GlanceException(msg) backend = self.__backends[backend_name] if isinstance(backend, tuple): name = backend[0] fromlist = backend[1] else: name = backend fromlist = backend self.__backend = __import__(name, None, None, fromlist) return self.__backend def __getattr__(self, key): backend = self.__get_backend() return getattr(backend, key) def validate_key_cert(key_file, cert_file): try: error_key_name = "private key" error_filename = key_file key_str = open(key_file, "r").read() key = crypto.load_privatekey(crypto.FILETYPE_PEM, key_str) error_key_name = "certficate" error_filename = cert_file cert_str = open(cert_file, "r").read() cert = crypto.load_certificate(crypto.FILETYPE_PEM, cert_str) except IOError as ioe: raise RuntimeError(_("There is a problem with your %(error_key_name)s " "%(error_filename)s. Please verify it." " Error: %(ioe)s") % {'error_key_name': error_key_name, 'error_filename': error_filename, 'ioe': ioe}) except crypto.Error as ce: raise RuntimeError(_("There is a problem with your %(error_key_name)s " "%(error_filename)s. Please verify it. OpenSSL" " error: %(ce)s") % {'error_key_name': error_key_name, 'error_filename': error_filename, 'ce': ce}) try: data = str(uuid.uuid4()) digest = "sha1" out = crypto.sign(key, data, digest) crypto.verify(cert, out, data, digest) except crypto.Error as ce: raise RuntimeError(_("There is a problem with your key pair. " "Please verify that cert %(cert_file)s and " "key %(key_file)s belong together. OpenSSL " "error %(ce)s") % {'cert_file': cert_file, 'key_file': key_file, 'ce': ce}) def get_test_suite_socket(): global GLANCE_TEST_SOCKET_FD_STR if GLANCE_TEST_SOCKET_FD_STR in os.environ: fd = int(os.environ[GLANCE_TEST_SOCKET_FD_STR]) sock = socket.fromfd(fd, socket.AF_INET, socket.SOCK_STREAM) sock = socket.SocketType(_sock=sock) sock.listen(CONF.backlog) del os.environ[GLANCE_TEST_SOCKET_FD_STR] os.close(fd) return sock return None def is_uuid_like(val): """Returns validation of a value as a UUID. For our purposes, a UUID is a canonical form string: aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa """ try: return str(uuid.UUID(val)) == val except (TypeError, ValueError, AttributeError): return False glance-2014.1/glance/common/config.py0000664000175400017540000002247712323736230020545 0ustar jenkinsjenkins00000000000000#!/usr/bin/env python # Copyright 2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ Routines for configuring Glance """ import logging import logging.config import logging.handlers import os from oslo.config import cfg from paste import deploy from glance.version import version_info as version paste_deploy_opts = [ cfg.StrOpt('flavor', help=_('Partial name of a pipeline in your paste configuration ' 'file with the service name removed. For example, if ' 'your paste section name is ' '[pipeline:glance-api-keystone] use the value ' '"keystone"')), cfg.StrOpt('config_file', help=_('Name of the paste configuration file.')), ] image_format_opts = [ cfg.ListOpt('container_formats', default=['ami', 'ari', 'aki', 'bare', 'ovf', 'ova'], help=_("Supported values for the 'container_format' " "image attribute"), deprecated_opts=[cfg.DeprecatedOpt('container_formats', group='DEFAULT')]), cfg.ListOpt('disk_formats', default=['ami', 'ari', 'aki', 'vhd', 'vmdk', 'raw', 'qcow2', 'vdi', 'iso'], help=_("Supported values for the 'disk_format' " "image attribute"), deprecated_opts=[cfg.DeprecatedOpt('disk_formats', group='DEFAULT')]), ] task_opts = [ cfg.IntOpt('task_time_to_live', default=48, help=_("Time in hours for which a task lives after, either " "succeeding or failing"), deprecated_opts=[cfg.DeprecatedOpt('task_time_to_live', group='DEFAULT')]), ] common_opts = [ cfg.BoolOpt('allow_additional_image_properties', default=True, help=_('Whether to allow users to specify image properties ' 'beyond what the image schema provides')), cfg.IntOpt('image_member_quota', default=128, help=_('Maximum number of image members per image. ' 'Negative values evaluate to unlimited.')), cfg.IntOpt('image_property_quota', default=128, help=_('Maximum number of properties allowed on an image. ' 'Negative values evaluate to unlimited.')), cfg.IntOpt('image_tag_quota', default=128, help=_('Maximum number of tags allowed on an image. ' 'Negative values evaluate to unlimited.')), cfg.IntOpt('image_location_quota', default=10, help=_('Maximum number of locations allowed on an image. ' 'Negative values evaluate to unlimited.')), cfg.StrOpt('data_api', default='glance.db.sqlalchemy.api', help=_('Python module path of data access API')), cfg.IntOpt('limit_param_default', default=25, help=_('Default value for the number of items returned by a ' 'request if not specified explicitly in the request')), cfg.IntOpt('api_limit_max', default=1000, help=_('Maximum permissible number of items that could be ' 'returned by a request')), cfg.BoolOpt('show_image_direct_url', default=False, help=_('Whether to include the backend image storage location ' 'in image properties. Revealing storage location can ' 'be a security risk, so use this setting with ' 'caution!')), cfg.BoolOpt('show_multiple_locations', default=False, help=_('Whether to include the backend image locations ' 'in image properties. Revealing storage location can ' 'be a security risk, so use this setting with ' 'caution! The overrides show_image_direct_url.')), cfg.IntOpt('image_size_cap', default=1099511627776, help=_("Maximum size of image a user can upload in bytes. " "Defaults to 1099511627776 bytes (1 TB).")), cfg.IntOpt('user_storage_quota', default=0, help=_("Set a system wide quota for every user. This value is " "the total number of bytes that a user can use across " "all storage systems. A value of 0 means unlimited.")), cfg.BoolOpt('enable_v1_api', default=True, help=_("Deploy the v1 OpenStack Images API.")), cfg.BoolOpt('enable_v2_api', default=True, help=_("Deploy the v2 OpenStack Images API.")), cfg.BoolOpt('enable_v1_registry', default=True, help=_("Deploy the v1 OpenStack Registry API.")), cfg.BoolOpt('enable_v2_registry', default=True, help=_("Deploy the v2 OpenStack Registry API.")), cfg.StrOpt('pydev_worker_debug_host', default=None, help=_('The hostname/IP of the pydev process listening for ' 'debug connections')), cfg.IntOpt('pydev_worker_debug_port', default=5678, help=_('The port on which a pydev process is listening for ' 'connections.')), cfg.StrOpt('metadata_encryption_key', secret=True, help=_('Key used for encrypting sensitive metadata while ' 'talking to the registry or database.')), ] CONF = cfg.CONF CONF.register_opts(paste_deploy_opts, group='paste_deploy') CONF.register_opts(image_format_opts, group='image_format') CONF.register_opts(task_opts, group='task') CONF.register_opts(common_opts) def parse_args(args=None, usage=None, default_config_files=None): CONF(args=args, project='glance', version=version.cached_version_string(), usage=usage, default_config_files=default_config_files) def parse_cache_args(args=None): config_files = cfg.find_config_files(project='glance', prog='glance-cache') parse_args(args=args, default_config_files=config_files) def _get_deployment_flavor(flavor=None): """ Retrieve the paste_deploy.flavor config item, formatted appropriately for appending to the application name. :param flavor: if specified, use this setting rather than the paste_deploy.flavor configuration setting """ if not flavor: flavor = CONF.paste_deploy.flavor return '' if not flavor else ('-' + flavor) def _get_paste_config_path(): paste_suffix = '-paste.ini' conf_suffix = '.conf' if CONF.config_file: # Assume paste config is in a paste.ini file corresponding # to the last config file path = CONF.config_file[-1].replace(conf_suffix, paste_suffix) else: path = CONF.prog + paste_suffix return CONF.find_file(os.path.basename(path)) def _get_deployment_config_file(): """ Retrieve the deployment_config_file config item, formatted as an absolute pathname. """ path = CONF.paste_deploy.config_file if not path: path = _get_paste_config_path() if not path: msg = _("Unable to locate paste config file for %s.") % CONF.prog raise RuntimeError(msg) return os.path.abspath(path) def load_paste_app(app_name, flavor=None, conf_file=None): """ Builds and returns a WSGI app from a paste config file. We assume the last config file specified in the supplied ConfigOpts object is the paste config file, if conf_file is None. :param app_name: name of the application to load :param flavor: name of the variant of the application to load :param conf_file: path to the paste config file :raises RuntimeError when config file cannot be located or application cannot be loaded from config file """ # append the deployment flavor to the application name, # in order to identify the appropriate paste pipeline app_name += _get_deployment_flavor(flavor) if not conf_file: conf_file = _get_deployment_config_file() try: logger = logging.getLogger(__name__) logger.debug(_("Loading %(app_name)s from %(conf_file)s"), {'conf_file': conf_file, 'app_name': app_name}) app = deploy.loadapp("config:%s" % conf_file, name=app_name) # Log the options used when starting if we're in debug mode... if CONF.debug: CONF.log_opt_values(logger, logging.DEBUG) return app except (LookupError, ImportError) as e: msg = (_("Unable to load %(app_name)s from " "configuration file %(conf_file)s." "\nGot: %(e)r") % {'app_name': app_name, 'conf_file': conf_file, 'e': e}) logger.error(msg) raise RuntimeError(msg) glance-2014.1/glance/common/property_utils.py0000664000175400017540000001726412323736226022407 0ustar jenkinsjenkins00000000000000# Copyright 2013 Rackspace # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import ConfigParser import re try: from collections import OrderedDict except ImportError: from ordereddict import OrderedDict from oslo.config import cfg import glance.api.policy from glance.common import exception from glance.openstack.common import log as logging from glance.openstack.common import policy # NOTE(bourke): The default dict_type is collections.OrderedDict in py27, but # we must set manually for compatibility with py26 CONFIG = ConfigParser.SafeConfigParser(dict_type=OrderedDict) LOG = logging.getLogger(__name__) property_opts = [ cfg.StrOpt('property_protection_file', default=None, help=_('The location of the property protection file.')), cfg.StrOpt('property_protection_rule_format', default='roles', help=_('This config value indicates whether "roles" or ' '"policies" are used in the property protection file.')), ] CONF = cfg.CONF CONF.register_opts(property_opts) # NOTE (spredzy): Due to the particularly lengthy name of the exception # and the number of occurrence it is raise in this file, a variable is # created InvalidPropProtectConf = exception.InvalidPropertyProtectionConfiguration def is_property_protection_enabled(): if CONF.property_protection_file: return True return False class PropertyRules(object): def __init__(self, policy_enforcer=None): self.rules = [] self.prop_exp_mapping = {} self.policies = [] self.policy_enforcer = policy_enforcer or glance.api.policy.Enforcer() self.prop_prot_rule_format = CONF.property_protection_rule_format self.prop_prot_rule_format = self.prop_prot_rule_format.lower() self._load_rules() def _load_rules(self): try: conf_file = CONF.find_file(CONF.property_protection_file) CONFIG.read(conf_file) except Exception as e: msg = (_("Couldn't find property protection file %(file)s: " "%(error)s.") % {'file': CONF.property_protection_file, 'error': e}) LOG.error(msg) raise InvalidPropProtectConf() if self.prop_prot_rule_format not in ['policies', 'roles']: msg = _("Invalid value '%s' for " "'property_protection_rule_format'. " "The permitted values are " "'roles' and 'policies'") % self.prop_prot_rule_format LOG.error(msg) raise InvalidPropProtectConf() operations = ['create', 'read', 'update', 'delete'] properties = CONFIG.sections() for property_exp in properties: property_dict = {} compiled_rule = self._compile_rule(property_exp) for operation in operations: permissions = CONFIG.get(property_exp, operation) if permissions: if self.prop_prot_rule_format == 'policies': if ',' in permissions: LOG.error( _("Multiple policies '%s' not allowed" "for a given operation. Policies can be " "combined in the policy file"), permissions) raise InvalidPropProtectConf() self.prop_exp_mapping[compiled_rule] = property_exp self._add_policy_rules(property_exp, operation, permissions) permissions = [permissions] else: permissions = [permission.strip() for permission in permissions.split(',')] if '@' in permissions and '!' in permissions: msg = (_( "Malformed property protection rule in " "[%(prop)s] %(op)s=%(perm)s: '@' and '!' " "are mutually exclusive") % dict(prop=property_exp, op=operation, perm=permissions)) LOG.error(msg) raise InvalidPropProtectConf() property_dict[operation] = permissions else: property_dict[operation] = [] LOG.warn( _('Property protection on operation %(operation)s' ' for rule %(rule)s is not found. No role will be' ' allowed to perform this operation.') % {'operation': operation, 'rule': property_exp}) self.rules.append((compiled_rule, property_dict)) def _compile_rule(self, rule): try: return re.compile(rule) except Exception as e: msg = (_("Encountered a malformed property protection rule" " %(rule)s: %(error)s.") % {'rule': rule, 'error': e}) LOG.error(msg) raise InvalidPropProtectConf() def _add_policy_rules(self, property_exp, action, rule): """Add policy rules to the policy enforcer. For example, if the file listed as property_protection_file has: [prop_a] create = glance_creator then the corresponding policy rule would be: "prop_a:create": "rule:glance_creator" where glance_creator is defined in policy.json. For example: "glance:creator": "role:admin or role:glance_create_user" """ rule = "rule:%s" % rule rule_name = "%s:%s" % (property_exp, action) rule_dict = {} rule_dict[rule_name] = policy.parse_rule(rule) self.policy_enforcer.add_rules(rule_dict) def _check_policy(self, property_exp, action, context): try: target = ":".join([property_exp, action]) self.policy_enforcer.enforce(context, target, {}) except exception.Forbidden: return False return True def check_property_rules(self, property_name, action, context): roles = context.roles if not self.rules: return True if action not in ['create', 'read', 'update', 'delete']: return False for rule_exp, rule in self.rules: if rule_exp.search(str(property_name)): break else: # no matching rules return False rule_roles = rule.get(action) if rule_roles: if '!' in rule_roles: return False elif '@' in rule_roles: return True if self.prop_prot_rule_format == 'policies': prop_exp_key = self.prop_exp_mapping[rule_exp] return self._check_policy(prop_exp_key, action, context) if set(roles).intersection(set(rule_roles)): return True return False glance-2014.1/glance/common/exception.py0000664000175400017540000002505012323736226021271 0ustar jenkinsjenkins00000000000000# Copyright 2010 United States Government as represented by the # Administrator of the National Aeronautics and Space Administration. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """Glance exception subclasses""" import six import six.moves.urllib.parse as urlparse _FATAL_EXCEPTION_FORMAT_ERRORS = False class RedirectException(Exception): def __init__(self, url): self.url = urlparse.urlparse(url) class GlanceException(Exception): """ Base Glance Exception To correctly use this class, inherit from it and define a 'message' property. That message will get printf'd with the keyword arguments provided to the constructor. """ message = _("An unknown exception occurred") def __init__(self, message=None, *args, **kwargs): if not message: message = self.message try: if kwargs: message = message % kwargs except Exception: if _FATAL_EXCEPTION_FORMAT_ERRORS: raise else: # at least get the core message out if something happened pass self.msg = message super(GlanceException, self).__init__(message) def __unicode__(self): # NOTE(flwang): By default, self.msg is an instance of Message, which # can't be converted by str(). Based on the definition of # __unicode__, it should return unicode always. return six.text_type(self.msg) class MissingCredentialError(GlanceException): message = _("Missing required credential: %(required)s") class BadAuthStrategy(GlanceException): message = _("Incorrect auth strategy, expected \"%(expected)s\" but " "received \"%(received)s\"") class NotFound(GlanceException): message = _("An object with the specified identifier was not found.") class UnknownScheme(GlanceException): message = _("Unknown scheme '%(scheme)s' found in URI") class BadStoreUri(GlanceException): message = _("The Store URI was malformed.") class Duplicate(GlanceException): message = _("An object with the same identifier already exists.") class Conflict(GlanceException): message = _("An object with the same identifier is currently being " "operated on.") class StorageFull(GlanceException): message = _("There is not enough disk space on the image storage media.") class StorageQuotaFull(GlanceException): message = _("The size of the data %(image_size)s will exceed the limit. " "%(remaining)s bytes remaining.") class StorageWriteDenied(GlanceException): message = _("Permission to write image storage media denied.") class AuthBadRequest(GlanceException): message = _("Connect error/bad request to Auth service at URL %(url)s.") class AuthUrlNotFound(GlanceException): message = _("Auth service at URL %(url)s not found.") class AuthorizationFailure(GlanceException): message = _("Authorization failed.") class NotAuthenticated(GlanceException): message = _("You are not authenticated.") class Forbidden(GlanceException): message = _("You are not authorized to complete this action.") class ForbiddenPublicImage(Forbidden): message = _("You are not authorized to complete this action.") class ProtectedImageDelete(Forbidden): message = _("Image %(image_id)s is protected and cannot be deleted.") class Invalid(GlanceException): message = _("Data supplied was not valid.") class InvalidSortKey(Invalid): message = _("Sort key supplied was not valid.") class InvalidPropertyProtectionConfiguration(Invalid): message = _("Invalid configuration in property protection file.") class InvalidFilterRangeValue(Invalid): message = _("Unable to filter using the specified range.") class ReadonlyProperty(Forbidden): message = _("Attribute '%(property)s' is read-only.") class ReservedProperty(Forbidden): message = _("Attribute '%(property)s' is reserved.") class AuthorizationRedirect(GlanceException): message = _("Redirecting to %(uri)s for authorization.") class ClientConnectionError(GlanceException): message = _("There was an error connecting to a server") class ClientConfigurationError(GlanceException): message = _("There was an error configuring the client.") class MultipleChoices(GlanceException): message = _("The request returned a 302 Multiple Choices. This generally " "means that you have not included a version indicator in a " "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 503 Service Unavilable. 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 ServerError(GlanceException): message = _("The request returned 500 Internal Server Error.") class UnexpectedStatus(GlanceException): message = _("The request returned an unexpected status: %(status)s." "\n\nThe response body:\n%(body)s") class InvalidContentType(GlanceException): message = _("Invalid content type %(content_type)s") class BadRegistryConnectionConfiguration(GlanceException): message = _("Registry was not configured correctly on API server. " "Reason: %(reason)s") class BadStoreConfiguration(GlanceException): message = _("Store %(store_name)s could not be configured correctly. " "Reason: %(reason)s") class BadDriverConfiguration(GlanceException): message = _("Driver %(driver_name)s could not be configured correctly. " "Reason: %(reason)s") class StoreDeleteNotSupported(GlanceException): message = _("Deleting images from this store is not supported.") class StoreGetNotSupported(GlanceException): message = _("Getting images from this store is not supported.") class StoreAddNotSupported(GlanceException): message = _("Adding images to this store is not supported.") class StoreAddDisabled(GlanceException): message = _("Configuration for store failed. Adding images to this " "store is disabled.") class MaxRedirectsExceeded(GlanceException): message = _("Maximum redirects (%(redirects)s) was exceeded.") class InvalidRedirect(GlanceException): message = _("Received invalid HTTP redirect.") class NoServiceEndpoint(GlanceException): message = _("Response from Keystone does not contain a Glance endpoint.") class RegionAmbiguity(GlanceException): message = _("Multiple 'image' service matches for region %(region)s. This " "generally means that a region is required and you have not " "supplied one.") class WorkerCreationFailure(GlanceException): message = _("Server worker creation failed: %(reason)s.") class SchemaLoadError(GlanceException): message = _("Unable to load schema: %(reason)s") class InvalidObject(GlanceException): message = _("Provided object does not match schema " "'%(schema)s': %(reason)s") class UnsupportedHeaderFeature(GlanceException): message = _("Provided header feature is unsupported: %(feature)s") class InUseByStore(GlanceException): message = _("The image cannot be deleted because it is in use through " "the backend store outside of Glance.") class ImageSizeLimitExceeded(GlanceException): message = _("The provided image is too large.") class ImageMemberLimitExceeded(LimitExceeded): message = _("The limit has been exceeded on the number of allowed image " "members for this image. Attempted: %(attempted)s, " "Maximum: %(maximum)s") class ImagePropertyLimitExceeded(LimitExceeded): message = _("The limit has been exceeded on the number of allowed image " "properties. Attempted: %(attempted)s, Maximum: %(maximum)s") class ImageTagLimitExceeded(LimitExceeded): message = _("The limit has been exceeded on the number of allowed image " "tags. Attempted: %(attempted)s, Maximum: %(maximum)s") class ImageLocationLimitExceeded(LimitExceeded): message = _("The limit has been exceeded on the number of allowed image " "locations. Attempted: %(attempted)s, Maximum: %(maximum)s") class RPCError(GlanceException): message = _("%(cls)s exception was raised in the last rpc call: %(val)s") class TaskException(GlanceException): message = _("An unknown task exception occurred") class TaskNotFound(TaskException, NotFound): message = _("Task with the given id %(task_id)s was not found") class InvalidTaskStatus(TaskException, Invalid): message = _("Provided status of task is unsupported: %(status)s") class InvalidTaskType(TaskException, Invalid): message = _("Provided type of task is unsupported: %(type)s") class InvalidTaskStatusTransition(TaskException, Invalid): message = _("Status transition from %(cur_status)s to" " %(new_status)s is not allowed") class DuplicateLocation(Duplicate): message = _("The location %(location)s already exists") class ImageDataNotFound(NotFound): message = _("No image data could be found") class InvalidParameterValue(Invalid): message = _("Invalid value '%(value)s' for parameter '%(param)s': " "%(extra_msg)s") class InvalidImageStatusTransition(Invalid): message = _("Image status transition from %(cur_status)s to" " %(new_status)s is not allowed") glance-2014.1/glance/common/client.py0000664000175400017540000005610512323736226020556 0ustar jenkinsjenkins00000000000000# Copyright 2010-2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # HTTPSClientAuthConnection code comes courtesy of ActiveState website: # http://code.activestate.com/recipes/ # 577548-https-httplib-client-connection-with-certificate-v/ import collections import copy import errno import functools import httplib import os import re try: from eventlet.green import socket from eventlet.green import ssl except ImportError: import socket import ssl try: import sendfile # noqa SENDFILE_SUPPORTED = True except ImportError: SENDFILE_SUPPORTED = False import six import six.moves.urllib.parse as urlparse from six.moves import xrange from glance.common import auth from glance.common import exception from glance.common import utils import glance.openstack.common.log as logging from glance.openstack.common import strutils LOG = logging.getLogger(__name__) # common chunk size for get and put CHUNKSIZE = 65536 VERSION_REGEX = re.compile(r"/?v[0-9\.]+") def handle_unauthenticated(func): """ Wrap a function to re-authenticate and retry. """ @functools.wraps(func) def wrapped(self, *args, **kwargs): try: return func(self, *args, **kwargs) except exception.NotAuthenticated: self._authenticate(force_reauth=True) return func(self, *args, **kwargs) return wrapped def handle_redirects(func): """ Wrap the _do_request function to handle HTTP redirects. """ MAX_REDIRECTS = 5 @functools.wraps(func) def wrapped(self, method, url, body, headers): for _ in xrange(MAX_REDIRECTS): try: return func(self, method, url, body, headers) except exception.RedirectException as redirect: if redirect.url is None: raise exception.InvalidRedirect() url = redirect.url raise exception.MaxRedirectsExceeded(redirects=MAX_REDIRECTS) return wrapped class HTTPSClientAuthConnection(httplib.HTTPSConnection): """ Class to make a HTTPS connection, with support for full client-based SSL Authentication :see http://code.activestate.com/recipes/ 577548-https-httplib-client-connection-with-certificate-v/ """ def __init__(self, host, port, key_file, cert_file, ca_file, timeout=None, insecure=False): httplib.HTTPSConnection.__init__(self, host, port, key_file=key_file, cert_file=cert_file) self.key_file = key_file self.cert_file = cert_file self.ca_file = ca_file self.timeout = timeout self.insecure = insecure def connect(self): """ Connect to a host on a given (SSL) port. If ca_file is pointing somewhere, use it to check Server Certificate. Redefined/copied and extended from httplib.py:1105 (Python 2.6.x). This is needed to pass cert_reqs=ssl.CERT_REQUIRED as parameter to ssl.wrap_socket(), which forces SSL to check server certificate against our client certificate. """ sock = socket.create_connection((self.host, self.port), self.timeout) if self._tunnel_host: self.sock = sock self._tunnel() # Check CA file unless 'insecure' is specificed if self.insecure is True: self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file, cert_reqs=ssl.CERT_NONE) else: self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file, ca_certs=self.ca_file, cert_reqs=ssl.CERT_REQUIRED) class BaseClient(object): """A base client class""" DEFAULT_PORT = 80 DEFAULT_DOC_ROOT = None # Standard CA file locations for Debian/Ubuntu, RedHat/Fedora, # Suse, FreeBSD/OpenBSD DEFAULT_CA_FILE_PATH = ('/etc/ssl/certs/ca-certificates.crt:' '/etc/pki/tls/certs/ca-bundle.crt:' '/etc/ssl/ca-bundle.pem:' '/etc/ssl/cert.pem') OK_RESPONSE_CODES = ( httplib.OK, httplib.CREATED, httplib.ACCEPTED, httplib.NO_CONTENT, ) REDIRECT_RESPONSE_CODES = ( httplib.MOVED_PERMANENTLY, httplib.FOUND, httplib.SEE_OTHER, httplib.USE_PROXY, httplib.TEMPORARY_REDIRECT, ) def __init__(self, host, port=None, timeout=None, use_ssl=False, auth_tok=None, creds=None, doc_root=None, key_file=None, cert_file=None, ca_file=None, insecure=False, configure_via_auth=True): """ Creates a new client to some service. :param host: The host where service resides :param port: The port where service resides :param timeout: Connection timeout. :param use_ssl: Should we use HTTPS? :param auth_tok: The auth token to pass to the server :param creds: The credentials to pass to the auth plugin :param doc_root: Prefix for all URLs we request from host :param key_file: Optional PEM-formatted file that contains the private key. If use_ssl is True, and this param is None (the default), then an environ variable GLANCE_CLIENT_KEY_FILE is looked for. If no such environ variable is found, ClientConnectionError will be raised. :param cert_file: Optional PEM-formatted certificate chain file. If use_ssl is True, and this param is None (the default), then an environ variable GLANCE_CLIENT_CERT_FILE is looked for. If no such environ variable is found, ClientConnectionError will be raised. :param ca_file: Optional CA cert file to use in SSL connections If use_ssl is True, and this param is None (the default), then an environ variable GLANCE_CLIENT_CA_FILE is looked for. :param insecure: Optional. If set then the server's certificate will not be verified. :param configure_via_auth: Optional. Defaults to True. If set, the URL returned from the service catalog for the image endpoint will **override** the URL supplied to in the host parameter. """ self.host = host self.port = port or self.DEFAULT_PORT self.timeout = timeout # A value of '0' implies never timeout if timeout == 0: self.timeout = None self.use_ssl = use_ssl 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.key_file = key_file self.cert_file = cert_file self.ca_file = ca_file self.insecure = insecure self.auth_plugin = self.make_auth_plugin(self.creds, self.insecure) self.connect_kwargs = self.get_connect_kwargs() def get_connect_kwargs(self): connect_kwargs = {} # Both secure and insecure connections have a timeout option connect_kwargs['timeout'] = self.timeout 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 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 " "key_file parameter or set the " "GLANCE_CLIENT_KEY_FILE environ variable") raise exception.ClientConnectionError(msg) 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 " "cert_file parameter or set the " "GLANCE_CLIENT_CERT_FILE environ variable") raise exception.ClientConnectionError(msg) 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") % self.key_file raise exception.ClientConnectionError(msg) connect_kwargs['key_file'] = self.key_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") % self.cert_file raise exception.ClientConnectionError(msg) connect_kwargs['cert_file'] = self.cert_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") % self.ca_file raise exception.ClientConnectionError(msg) if self.ca_file is None: for ca in self.DEFAULT_CA_FILE_PATH.split(":"): if os.path.exists(ca): self.ca_file = ca break connect_kwargs['ca_file'] = self.ca_file connect_kwargs['insecure'] = self.insecure return connect_kwargs def set_auth_token(self, auth_tok): """ Updates the authentication token for this client connection. """ # FIXME(sirp): Nova image/glance.py currently calls this. Since this # method isn't really doing anything useful[1], we should go ahead and # rip it out, first in Nova, then here. Steps: # # 1. Change auth_tok in Glance to auth_token # 2. Change image/glance.py in Nova to use client.auth_token # 3. Remove this method # # [1] http://mail.python.org/pipermail/tutor/2003-October/025932.html self.auth_tok = auth_tok def configure_from_url(self, url): """ Setups the connection based on the given url. The form is: ://:port/doc_root """ LOG.debug(_("Configuring from URL: %s"), url) parsed = urlparse.urlparse(url) self.use_ssl = parsed.scheme == 'https' self.host = parsed.hostname self.port = parsed.port or 80 self.doc_root = parsed.path.rstrip('/') # We need to ensure a version identifier is appended to the doc_root if not VERSION_REGEX.match(self.doc_root): if self.DEFAULT_DOC_ROOT: doc_root = self.DEFAULT_DOC_ROOT.lstrip('/') self.doc_root += '/' + doc_root msg = (_("Appending doc_root %(doc_root)s to URL %(url)s") % {'doc_root': doc_root, 'url': url}) LOG.debug(msg) # 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, insecure): """ Returns an instantiated authentication plugin. """ strategy = creds.get('strategy', 'noauth') plugin = auth.get_plugin_from_strategy(strategy, creds, insecure, self.configure_via_auth) return plugin def get_connection_type(self): """ Returns the proper connection type """ if self.use_ssl: return HTTPSClientAuthConnection else: return httplib.HTTPConnection def _authenticate(self, force_reauth=False): """ Use the authentication plugin to authenticate and set the auth token. :param force_reauth: For re-authentication to bypass cache. """ auth_plugin = self.auth_plugin if not auth_plugin.is_authenticated or force_reauth: auth_plugin.authenticate() self.auth_tok = auth_plugin.auth_token management_url = auth_plugin.management_url if management_url and self.configure_via_auth: self.configure_from_url(management_url) @handle_unauthenticated def do_request(self, method, action, body=None, headers=None, params=None): """ Make a request, returning an HTTP response object. :param method: HTTP verb (GET, POST, PUT, etc.) :param action: Requested path to append to self.doc_root :param body: Data to send in the body of the request :param headers: Headers to send with the request :param params: Key/value pairs to use in query string :returns: HTTP response object """ if not self.auth_tok: self._authenticate() url = self._construct_url(action, params) # NOTE(ameade): We need to copy these kwargs since they can be altered # in _do_request but we need the originals if handle_unauthenticated # calls this function again. return self._do_request(method=method, url=url, body=copy.deepcopy(body), headers=copy.deepcopy(headers)) def _construct_url(self, action, params=None): """ Create a URL object we can use to pass to _do_request(). """ action = urlparse.quote(action) path = '/'.join([self.doc_root or '', action.lstrip('/')]) scheme = "https" if self.use_ssl else "http" netloc = "%s:%d" % (self.host, self.port) if isinstance(params, dict): for (key, value) in params.items(): if value is None: del params[key] continue if not isinstance(value, six.string_types): value = str(value) params[key] = strutils.safe_encode(value) query = urlparse.urlencode(params) else: query = None url = urlparse.ParseResult(scheme, netloc, path, '', query, '') log_msg = _("Constructed URL: %s") LOG.debug(log_msg, url.geturl()) return url def _encode_headers(self, headers): """ Encodes headers. Note: This should be used right before sending anything out. :param headers: Headers to encode :returns: Dictionary with encoded headers' names and values """ to_str = strutils.safe_encode return dict([(to_str(h), to_str(v)) for h, v in headers.iteritems()]) @handle_redirects def _do_request(self, method, url, body, headers): """ Connects to the server and issues a request. Handles converting any returned HTTP error status codes to OpenStack/Glance exceptions and closing the server connection. Returns the result data, or raises an appropriate exception. :param method: HTTP method ("GET", "POST", "PUT", etc...) :param url: urlparse.ParsedResult object with URL information :param body: data to send (as string, filelike or iterable), or None (default) :param headers: mapping of key/value pairs to add as headers :note If the body param has a read attribute, and method is either POST or PUT, this method will automatically conduct a chunked-transfer encoding and use the body as a file object or iterable, transferring chunks of data using the connection's send() method. This allows large objects to be transferred efficiently without buffering the entire body in memory. """ if url.query: path = url.path + "?" + url.query else: path = url.path try: connection_type = self.get_connection_type() headers = self._encode_headers(headers or {}) if 'x-auth-token' not in headers and self.auth_tok: headers['x-auth-token'] = self.auth_tok c = connection_type(url.hostname, url.port, **self.connect_kwargs) def _pushing(method): return method.lower() in ('post', 'put') def _simple(body): return body is None or isinstance(body, six.string_types) def _filelike(body): return hasattr(body, 'read') def _sendbody(connection, iter): connection.endheaders() for sent in iter: # iterator has done the heavy lifting pass def _chunkbody(connection, iter): connection.putheader('Transfer-Encoding', 'chunked') connection.endheaders() for chunk in iter: connection.send('%x\r\n%s\r\n' % (len(chunk), chunk)) connection.send('0\r\n\r\n') # Do a simple request or a chunked request, depending # on whether the body param is file-like or iterable and # the method is PUT or POST # if not _pushing(method) or _simple(body): # Simple request... c.request(method, path, body, headers) elif _filelike(body) or self._iterable(body): c.putrequest(method, path) use_sendfile = self._sendable(body) # According to HTTP/1.1, Content-Length and Transfer-Encoding # conflict. for header, value in headers.items(): if use_sendfile or header.lower() != 'content-length': c.putheader(header, str(value)) iter = self.image_iterator(c, headers, body) if use_sendfile: # send actual file without copying into userspace _sendbody(c, iter) else: # otherwise iterate and chunk _chunkbody(c, iter) else: 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 elif status_code in self.REDIRECT_RESPONSE_CODES: raise exception.RedirectException(res.getheader('Location')) elif status_code == httplib.UNAUTHORIZED: raise exception.NotAuthenticated(res.read()) elif status_code == httplib.FORBIDDEN: raise exception.Forbidden(res.read()) elif status_code == httplib.NOT_FOUND: raise exception.NotFound(res.read()) elif status_code == httplib.CONFLICT: raise exception.Duplicate(res.read()) elif status_code == httplib.BAD_REQUEST: 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.ServerError() elif status_code == httplib.SERVICE_UNAVAILABLE: raise exception.ServiceUnavailable(retry=_retry(res)) else: raise exception.UnexpectedStatus(status=status_code, body=res.read()) except (socket.error, IOError) as e: raise exception.ClientConnectionError(e) def _seekable(self, body): # pipes are not seekable, avoids sendfile() failure on e.g. # cat /path/to/image | glance add ... # or where add command is launched via popen try: os.lseek(body.fileno(), 0, os.SEEK_CUR) return True except OSError as e: return (e.errno != errno.ESPIPE) def _sendable(self, body): return (SENDFILE_SUPPORTED and hasattr(body, 'fileno') and self._seekable(body) and not self.use_ssl) def _iterable(self, body): return isinstance(body, collections.Iterable) def image_iterator(self, connection, headers, body): if self._sendable(body): return SendFileIterator(connection, body) elif self._iterable(body): return utils.chunkreadable(body) else: return ImageBodyIterator(body) def get_status_code(self, response): """ Returns the integer status code from the response, which can be either a Webob.Response (used in testing) or httplib.Response """ if hasattr(response, 'status_int'): return response.status_int else: return response.status def _extract_params(self, actual_params, allowed_params): """ Extract a subset of keys from a dictionary. The filters key will also be extracted, and each of its values will be returned as an individual param. :param actual_params: dict of keys to filter :param allowed_params: list of keys that 'actual_params' will be reduced to :retval subset of 'params' dict """ try: # expect 'filters' param to be a dict here result = dict(actual_params.get('filters')) except TypeError: result = {} for allowed_param in allowed_params: if allowed_param in actual_params: result[allowed_param] = actual_params[allowed_param] return result glance-2014.1/glance/common/auth.py0000664000175400017540000002362212323736226020237 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ This auth module is intended to allow OpenStack client-tools to select from a variety of authentication strategies, including NoAuth (the default), and Keystone (an identity management system). > auth_plugin = AuthPlugin(creds) > auth_plugin.authenticate() > auth_plugin.auth_token abcdefg > auth_plugin.management_url http://service_endpoint/ """ import httplib2 import six.moves.urllib.parse as urlparse from glance.common import exception from glance.openstack.common import jsonutils import glance.openstack.common.log as logging LOG = logging.getLogger(__name__) class BaseStrategy(object): def __init__(self): self.auth_token = None # TODO(sirp): Should expose selecting public/internal/admin URL. self.management_url = None def authenticate(self): raise NotImplementedError @property def is_authenticated(self): raise NotImplementedError @property def strategy(self): raise NotImplementedError class NoAuthStrategy(BaseStrategy): def authenticate(self): pass @property def is_authenticated(self): return True @property def strategy(self): return 'noauth' class KeystoneStrategy(BaseStrategy): MAX_REDIRECTS = 10 def __init__(self, creds, insecure=False, configure_via_auth=True): self.creds = creds self.insecure = insecure self.configure_via_auth = configure_via_auth super(KeystoneStrategy, self).__init__() def check_auth_params(self): # Ensure that supplied credential parameters are as required for required in ('username', 'password', 'auth_url', 'strategy'): if self.creds.get(required) is None: raise exception.MissingCredentialError(required=required) if self.creds['strategy'] != 'keystone': raise exception.BadAuthStrategy(expected='keystone', received=self.creds['strategy']) # For v2.0 also check tenant is present if self.creds['auth_url'].rstrip('/').endswith('v2.0'): if self.creds.get("tenant") is None: raise exception.MissingCredentialError(required='tenant') def authenticate(self): """Authenticate with the Keystone service. There are a few scenarios to consider here: 1. Which version of Keystone are we using? v1 which uses headers to pass the credentials, or v2 which uses a JSON encoded request body? 2. Keystone may respond back with a redirection using a 305 status code. 3. We may attempt a v1 auth when v2 is what's called for. In this case, we rewrite the url to contain /v2.0/ and retry using the v2 protocol. """ def _authenticate(auth_url): # If OS_AUTH_URL is missing a trailing slash add one if not auth_url.endswith('/'): auth_url += '/' token_url = urlparse.urljoin(auth_url, "tokens") # 1. Check Keystone version is_v2 = auth_url.rstrip('/').endswith('v2.0') if is_v2: self._v2_auth(token_url) else: self._v1_auth(token_url) self.check_auth_params() auth_url = self.creds['auth_url'] for _ in range(self.MAX_REDIRECTS): try: _authenticate(auth_url) except exception.AuthorizationRedirect as e: # 2. Keystone may redirect us auth_url = e.url except exception.AuthorizationFailure: # 3. In some configurations nova makes redirection to # v2.0 keystone endpoint. Also, new location does not # contain real endpoint, only hostname and port. if 'v2.0' not in auth_url: auth_url = urlparse.urljoin(auth_url, 'v2.0/') else: # If we successfully auth'd, then memorize the correct auth_url # for future use. self.creds['auth_url'] = auth_url break else: # Guard against a redirection loop raise exception.MaxRedirectsExceeded(redirects=self.MAX_REDIRECTS) def _v1_auth(self, token_url): creds = self.creds headers = {} headers['X-Auth-User'] = creds['username'] headers['X-Auth-Key'] = creds['password'] tenant = creds.get('tenant') if tenant: headers['X-Auth-Tenant'] = tenant resp, resp_body = self._do_request(token_url, 'GET', headers=headers) def _management_url(self, resp): for url_header in ('x-image-management-url', 'x-server-management-url', 'x-glance'): try: return resp[url_header] except KeyError as e: not_found = e raise not_found if resp.status in (200, 204): try: if self.configure_via_auth: self.management_url = _management_url(self, resp) self.auth_token = resp['x-auth-token'] except KeyError: raise exception.AuthorizationFailure() elif resp.status == 305: raise exception.AuthorizationRedirect(uri=resp['location']) elif resp.status == 400: raise exception.AuthBadRequest(url=token_url) elif resp.status == 401: raise exception.NotAuthenticated() elif resp.status == 404: raise exception.AuthUrlNotFound(url=token_url) else: raise Exception(_('Unexpected response: %s') % resp.status) def _v2_auth(self, token_url): creds = self.creds creds = { "auth": { "tenantName": creds['tenant'], "passwordCredentials": { "username": creds['username'], "password": creds['password'] } } } headers = {} headers['Content-Type'] = 'application/json' req_body = jsonutils.dumps(creds) resp, resp_body = self._do_request( token_url, 'POST', headers=headers, body=req_body) if resp.status == 200: resp_auth = jsonutils.loads(resp_body)['access'] creds_region = self.creds.get('region') if self.configure_via_auth: endpoint = get_endpoint(resp_auth['serviceCatalog'], endpoint_region=creds_region) self.management_url = endpoint self.auth_token = resp_auth['token']['id'] elif resp.status == 305: raise exception.RedirectException(resp['location']) elif resp.status == 400: raise exception.AuthBadRequest(url=token_url) elif resp.status == 401: raise exception.NotAuthenticated() elif resp.status == 404: raise exception.AuthUrlNotFound(url=token_url) else: raise Exception(_('Unexpected response: %s') % resp.status) @property def is_authenticated(self): return self.auth_token is not None @property def strategy(self): return 'keystone' def _do_request(self, url, method, headers=None, body=None): headers = headers or {} conn = httplib2.Http() conn.force_exception_to_status_code = True conn.disable_ssl_certificate_validation = self.insecure headers['User-Agent'] = 'glance-client' resp, resp_body = conn.request(url, method, headers=headers, body=body) return resp, resp_body def get_plugin_from_strategy(strategy, creds=None, insecure=False, configure_via_auth=True): if strategy == 'noauth': return NoAuthStrategy() elif strategy == 'keystone': return KeystoneStrategy(creds, insecure, configure_via_auth=configure_via_auth) else: raise Exception(_("Unknown auth strategy '%s'") % strategy) def get_endpoint(service_catalog, service_type='image', endpoint_region=None, endpoint_type='publicURL'): """ Select an endpoint from the service catalog We search the full service catalog for services matching both type and region. If the client supplied no region then any 'image' endpoint is considered a match. There must be one -- and only one -- successful match in the catalog, otherwise we will raise an exception. """ endpoint = None for service in service_catalog: s_type = None try: s_type = service['type'] except KeyError: msg = _('Encountered service with no "type": %s') % s_type LOG.warn(msg) continue if s_type == service_type: for ep in service['endpoints']: if endpoint_region is None or endpoint_region == ep['region']: if endpoint is not None: # This is a second match, abort raise exception.RegionAmbiguity(region=endpoint_region) endpoint = ep if endpoint and endpoint.get(endpoint_type): return endpoint[endpoint_type] else: raise exception.NoServiceEndpoint() glance-2014.1/glance/common/__init__.py0000664000175400017540000000000012323736226021016 0ustar jenkinsjenkins00000000000000glance-2014.1/glance/context.py0000664000175400017540000000721312323736226017470 0ustar jenkinsjenkins00000000000000# Copyright 2011-2012 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import uuid from glance.api import policy from glance.openstack.common import local class RequestContext(object): """ Stores information about the security context under which the user accesses the system, as well as additional request information. """ user_idt_format = '{user} {tenant} {domain} {user_domain} {p_domain}' def __init__(self, auth_tok=None, user=None, tenant=None, roles=None, is_admin=False, read_only=False, show_deleted=False, owner_is_tenant=True, service_catalog=None, policy_enforcer=None, domain=None, user_domain=None, project_domain=None): self.auth_tok = auth_tok self.user = user self.tenant = tenant self.roles = roles or [] self.read_only = read_only self._show_deleted = show_deleted self.owner_is_tenant = owner_is_tenant self.request_id = str(uuid.uuid4()) self.service_catalog = service_catalog self.policy_enforcer = policy_enforcer or policy.Enforcer() self.is_admin = is_admin self.domain = domain self.user_domain = user_domain self.project_domain = project_domain if not self.is_admin: self.is_admin = \ self.policy_enforcer.check_is_admin(self) if not hasattr(local.store, 'context'): self.update_store() def to_dict(self): # NOTE(ameade): These keys are named to correspond with the default # format string for logging the context in openstack common user_idt = ( self.user_idt_format.format(user=self.user or '-', tenant=self.tenant or '-', domain=self.domain or '-', user_domain=self.user_domain or '-', p_domain=self.project_domain or '-')) return { 'request_id': self.request_id, #NOTE(bcwaldon): openstack-common logging expects 'user' 'user': self.user, 'user_id': self.user, #NOTE(bcwaldon): openstack-common logging expects 'tenant' 'tenant': self.tenant, 'tenant_id': self.tenant, 'project_id': self.tenant, 'is_admin': self.is_admin, 'read_deleted': self.show_deleted, 'roles': self.roles, 'auth_token': self.auth_tok, 'service_catalog': self.service_catalog, 'user_identity': user_idt } @classmethod def from_dict(cls, values): return cls(**values) def update_store(self): local.store.context = self @property def owner(self): """Return the owner to correlate with an image.""" return self.tenant if self.owner_is_tenant else self.user @property def show_deleted(self): """Admins can see deleted by default""" if self._show_deleted or self.is_admin: return True return False glance-2014.1/glance/schema.py0000664000175400017540000001005112323736226017236 0ustar jenkinsjenkins00000000000000# Copyright 2012 OpenStack Foundation. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import jsonschema import six from glance.common import exception class Schema(object): def __init__(self, name, properties=None, links=None): self.name = name if properties is None: properties = {} self.properties = properties self.links = links def validate(self, obj): try: jsonschema.validate(obj, self.raw()) except jsonschema.ValidationError as e: raise exception.InvalidObject(schema=self.name, reason=six.text_type(e)) def filter(self, obj): filtered = {} for key, value in obj.iteritems(): if self._filter_func(self.properties, key) and value is not None: filtered[key] = value return filtered @staticmethod def _filter_func(properties, key): return key in properties def merge_properties(self, properties): # Ensure custom props aren't attempting to override base props original_keys = set(self.properties.keys()) new_keys = set(properties.keys()) intersecting_keys = original_keys.intersection(new_keys) conflicting_keys = [k for k in intersecting_keys if self.properties[k] != properties[k]] if conflicting_keys: props = ', '.join(conflicting_keys) reason = _("custom properties (%(props)s) conflict " "with base properties") raise exception.SchemaLoadError(reason=reason % {'props': props}) self.properties.update(properties) def raw(self): raw = { 'name': self.name, 'properties': self.properties, 'additionalProperties': False, } if self.links: raw['links'] = self.links return raw def minimal(self): minimal = { 'name': self.name, 'properties': self.properties } return minimal class PermissiveSchema(Schema): @staticmethod def _filter_func(properties, key): return True def raw(self): raw = super(PermissiveSchema, self).raw() raw['additionalProperties'] = {'type': 'string'} return raw def minimal(self): minimal = super(PermissiveSchema, self).raw() return minimal class CollectionSchema(object): def __init__(self, name, item_schema): self.name = name self.item_schema = item_schema def raw(self): return { 'name': self.name, 'properties': { self.name: { 'type': 'array', 'items': self.item_schema.raw(), }, 'first': {'type': 'string'}, 'next': {'type': 'string'}, 'schema': {'type': 'string'}, }, 'links': [ {'rel': 'first', 'href': '{first}'}, {'rel': 'next', 'href': '{next}'}, {'rel': 'describedby', 'href': '{schema}'}, ], } def minimal(self): return { 'name': self.name, 'properties': { self.name: { 'type': 'array', 'items': self.item_schema.minimal(), }, 'schema': {'type': 'string'}, }, 'links': [ {'rel': 'describedby', 'href': '{schema}'}, ], } glance-2014.1/glance/image_cache/0000775000175400017540000000000012323736427017637 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/image_cache/cleaner.py0000664000175400017540000000143512323736226021622 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ Cleans up any invalid cache entries """ from glance.image_cache import base class Cleaner(base.CacheApp): def run(self): self.cache.clean() glance-2014.1/glance/image_cache/drivers/0000775000175400017540000000000012323736427021315 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/image_cache/drivers/xattr.py0000664000175400017540000004057112323736230023030 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ Cache driver that uses xattr file tags and requires a filesystem that has atimes set. Assumptions =========== 1. Cache data directory exists on a filesytem that updates atime on reads ('noatime' should NOT be set) 2. Cache data directory exists on a filesystem that supports xattrs. This is optional, but highly recommended since it allows us to present ops with useful information pertaining to the cache, like human readable filenames and statistics. 3. `glance-prune` is scheduled to run as a periodic job via cron. This is needed to run the LRU prune strategy to keep the cache size within the limits set by the config file. Cache Directory Notes ===================== The image cache data directory contains the main cache path, where the active cache entries and subdirectories for handling partial downloads and errored-out cache images. The layout looks like: $image_cache_dir/ entry1 entry2 ... incomplete/ invalid/ queue/ """ from __future__ import absolute_import from contextlib import contextmanager import errno import os import stat import time from oslo.config import cfg import six import xattr from glance.common import exception from glance.image_cache.drivers import base import glance.openstack.common.log as logging LOG = logging.getLogger(__name__) CONF = cfg.CONF class Driver(base.Driver): """ Cache driver that uses xattr file tags and requires a filesystem that has atimes set. """ def configure(self): """ Configure the driver to use the stored configuration options Any store that needs special configuration should implement this method. If the store was not able to successfully configure itself, it should raise `exception.BadDriverConfiguration` """ # Here we set up the various file-based image cache paths # that we need in order to find the files in different states # of cache management. self.set_paths() # We do a quick attempt to write a user xattr to a temporary file # to check that the filesystem is even enabled to support xattrs image_cache_dir = self.base_dir fake_image_filepath = os.path.join(image_cache_dir, 'checkme') with open(fake_image_filepath, 'wb') as fake_file: fake_file.write("XXX") fake_file.flush() try: set_xattr(fake_image_filepath, 'hits', '1') except IOError as e: if e.errno == errno.EOPNOTSUPP: msg = (_("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.") % {'image_cache_dir': image_cache_dir}) LOG.error(msg) raise exception.BadDriverConfiguration(driver_name="xattr", reason=msg) else: # Cleanup after ourselves... if os.path.exists(fake_image_filepath): os.unlink(fake_image_filepath) def get_cache_size(self): """ Returns the total size in bytes of the image cache. """ sizes = [] for path in get_all_regular_files(self.base_dir): file_info = os.stat(path) sizes.append(file_info[stat.ST_SIZE]) return sum(sizes) def get_hit_count(self, image_id): """ Return the number of hits that an image has. :param image_id: Opaque image identifier """ if not self.is_cached(image_id): return 0 path = self.get_image_filepath(image_id) return int(get_xattr(path, 'hits', default=0)) def get_cached_images(self): """ Returns a list of records about cached images. """ LOG.debug(_("Gathering cached image entries.")) entries = [] for path in get_all_regular_files(self.base_dir): image_id = os.path.basename(path) entry = {} entry['image_id'] = image_id file_info = os.stat(path) entry['last_modified'] = file_info[stat.ST_MTIME] entry['last_accessed'] = file_info[stat.ST_ATIME] entry['size'] = file_info[stat.ST_SIZE] entry['hits'] = self.get_hit_count(image_id) entries.append(entry) entries.sort() # Order by ID return entries def is_cached(self, image_id): """ Returns True if the image with the supplied ID has its image file cached. :param image_id: Image ID """ return os.path.exists(self.get_image_filepath(image_id)) def is_cacheable(self, image_id): """ Returns True if the image with the supplied ID can have its image file cached, False otherwise. :param image_id: Image ID """ # Make sure we're not already cached or caching the image return not (self.is_cached(image_id) or self.is_being_cached(image_id)) def is_being_cached(self, image_id): """ Returns True if the image with supplied id is currently in the process of having its image file cached. :param image_id: Image ID """ path = self.get_image_filepath(image_id, 'incomplete') return os.path.exists(path) def is_queued(self, image_id): """ Returns True if the image identifier is in our cache queue. """ path = self.get_image_filepath(image_id, 'queue') return os.path.exists(path) def delete_all_cached_images(self): """ Removes all cached image files and any attributes about the images """ deleted = 0 for path in get_all_regular_files(self.base_dir): delete_cached_file(path) deleted += 1 return deleted def delete_cached_image(self, image_id): """ Removes a specific cached image file and any attributes about the image :param image_id: Image ID """ path = self.get_image_filepath(image_id) delete_cached_file(path) def delete_all_queued_images(self): """ Removes all queued image files and any attributes about the images """ files = [f for f in get_all_regular_files(self.queue_dir)] for file in files: os.unlink(file) return len(files) def delete_queued_image(self, image_id): """ Removes a specific queued image file and any attributes about the image :param image_id: Image ID """ path = self.get_image_filepath(image_id, 'queue') if os.path.exists(path): os.unlink(path) def get_least_recently_accessed(self): """ Return a tuple containing the image_id and size of the least recently accessed cached file, or None if no cached files. """ stats = [] for path in get_all_regular_files(self.base_dir): file_info = os.stat(path) stats.append((file_info[stat.ST_ATIME], # access time file_info[stat.ST_SIZE], # size in bytes path)) # absolute path if not stats: return None stats.sort() return os.path.basename(stats[0][2]), stats[0][1] @contextmanager def open_for_write(self, image_id): """ Open a file for writing the image file for an image with supplied identifier. :param image_id: Image ID """ incomplete_path = self.get_image_filepath(image_id, 'incomplete') def set_attr(key, value): set_xattr(incomplete_path, key, value) def commit(): set_attr('hits', 0) final_path = self.get_image_filepath(image_id) LOG.debug(_("Fetch finished, moving " "'%(incomplete_path)s' to '%(final_path)s'"), dict(incomplete_path=incomplete_path, final_path=final_path)) os.rename(incomplete_path, final_path) # Make sure that we "pop" the image from the queue... if self.is_queued(image_id): LOG.debug(_("Removing image '%s' from queue after " "caching it."), image_id) os.unlink(self.get_image_filepath(image_id, 'queue')) def rollback(e): set_attr('error', six.text_type(e)) invalid_path = self.get_image_filepath(image_id, 'invalid') LOG.debug(_("Fetch of cache file failed (%(e)s), rolling back by " "moving '%(incomplete_path)s' to " "'%(invalid_path)s'"), {'e': six.text_type(e), 'incomplete_path': incomplete_path, 'invalid_path': invalid_path}) os.rename(incomplete_path, invalid_path) try: with open(incomplete_path, 'wb') as cache_file: yield cache_file except Exception as e: rollback(e) raise else: commit() finally: # if the generator filling the cache file neither raises an # exception, nor completes fetching all data, neither rollback # nor commit will have been called, so the incomplete file # will persist - in that case remove it as it is unusable # example: ^c from client fetch if os.path.exists(incomplete_path): rollback('incomplete fetch') @contextmanager def open_for_read(self, image_id): """ Open and yield file for reading the image file for an image with supplied identifier. :param image_id: Image ID """ path = self.get_image_filepath(image_id) with open(path, 'rb') as cache_file: yield cache_file path = self.get_image_filepath(image_id) inc_xattr(path, 'hits', 1) def queue_image(self, image_id): """ This adds a image to be cache to the queue. If the image already exists in the queue or has already been cached, we return False, True otherwise :param image_id: Image ID """ if self.is_cached(image_id): msg = _("Not queueing image '%s'. Already cached.") % image_id LOG.warn(msg) return False if self.is_being_cached(image_id): msg = _("Not queueing image '%s'. Already being " "written to cache") % image_id LOG.warn(msg) return False if self.is_queued(image_id): msg = _("Not queueing image '%s'. Already queued.") % image_id LOG.warn(msg) return False path = self.get_image_filepath(image_id, 'queue') LOG.debug(_("Queueing image '%s'."), image_id) # Touch the file to add it to the queue with open(path, "w"): pass return True def get_queued_images(self): """ Returns a list of image IDs that are in the queue. The list should be sorted by the time the image ID was inserted into the queue. """ files = [f for f in get_all_regular_files(self.queue_dir)] items = [] for path in files: mtime = os.path.getmtime(path) items.append((mtime, os.path.basename(path))) items.sort() return [image_id for (mtime, image_id) in items] def _reap_old_files(self, dirpath, entry_type, grace=None): now = time.time() reaped = 0 for path in get_all_regular_files(dirpath): mtime = os.path.getmtime(path) age = now - mtime if not grace: LOG.debug(_("No grace period, reaping '%(path)s'" " immediately"), {'path': path}) delete_cached_file(path) reaped += 1 elif age > grace: LOG.debug(_("Cache entry '%(path)s' exceeds grace period, " "(%(age)i s > %(grace)i s)"), {'path': path, 'age': age, 'grace': grace}) delete_cached_file(path) reaped += 1 LOG.info(_("Reaped %(reaped)s %(entry_type)s cache entries"), {'reaped': reaped, 'entry_type': entry_type}) return reaped def reap_invalid(self, grace=None): """Remove any invalid cache entries :param grace: Number of seconds to keep an invalid entry around for debugging purposes. If None, then delete immediately. """ return self._reap_old_files(self.invalid_dir, 'invalid', grace=grace) def reap_stalled(self, grace=None): """Remove any stalled cache entries :param grace: Number of seconds to keep an invalid entry around for debugging purposes. If None, then delete immediately. """ return self._reap_old_files(self.incomplete_dir, 'stalled', grace=grace) def clean(self, stall_time=None): """ Delete any image files in the invalid directory and any files in the incomplete directory that are older than a configurable amount of time. """ self.reap_invalid() if stall_time is None: stall_time = CONF.image_cache_stall_time self.reap_stalled(stall_time) def get_all_regular_files(basepath): for fname in os.listdir(basepath): path = os.path.join(basepath, fname) if os.path.isfile(path): yield path def delete_cached_file(path): if os.path.exists(path): LOG.debug(_("Deleting image cache file '%s'"), path) os.unlink(path) else: LOG.warn(_("Cached image file '%s' doesn't exist, unable to" " delete"), path) def _make_namespaced_xattr_key(key, namespace='user'): """ Create a fully-qualified xattr-key by including the intended namespace. Namespacing differs among OSes[1]: FreeBSD: user, system Linux: user, system, trusted, security MacOS X: not needed Mac OS X won't break if we include a namespace qualifier, so, for simplicity, we always include it. -- [1] http://en.wikipedia.org/wiki/Extended_file_attributes """ namespaced_key = ".".join([namespace, key]) return namespaced_key def get_xattr(path, key, **kwargs): """Return the value for a particular xattr If the key doesn't not exist, or xattrs aren't supported by the file system then a KeyError will be raised, that is, unless you specify a default using kwargs. """ namespaced_key = _make_namespaced_xattr_key(key) try: return xattr.getxattr(path, namespaced_key) except IOError: if 'default' in kwargs: return kwargs['default'] else: raise def set_xattr(path, key, value): """Set the value of a specified xattr. If xattrs aren't supported by the file-system, we skip setting the value. """ namespaced_key = _make_namespaced_xattr_key(key) xattr.setxattr(path, namespaced_key, str(value)) def inc_xattr(path, key, n=1): """ Increment the value of an xattr (assuming it is an integer). BEWARE, this code *does* have a RACE CONDITION, since the read/update/write sequence is not atomic. Since the use-case for this function is collecting stats--not critical-- the benefits of simple, lock-free code out-weighs the possibility of an occasional hit not being counted. """ count = int(get_xattr(path, key)) count += n set_xattr(path, key, str(count)) glance-2014.1/glance/image_cache/drivers/sqlite.py0000664000175400017540000004034112323736230023162 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ Cache driver that uses SQLite to store information about cached images """ from __future__ import absolute_import from contextlib import contextmanager import os import stat import time from eventlet import sleep from eventlet import timeout from oslo.config import cfg import sqlite3 from glance.common import exception from glance.image_cache.drivers import base import glance.openstack.common.log as logging LOG = logging.getLogger(__name__) sqlite_opts = [ cfg.StrOpt('image_cache_sqlite_db', default='cache.db', help=_('The path to the sqlite file database that will be ' 'used for image cache management.')), ] CONF = cfg.CONF CONF.register_opts(sqlite_opts) DEFAULT_SQL_CALL_TIMEOUT = 2 class SqliteConnection(sqlite3.Connection): """ SQLite DB Connection handler that plays well with eventlet, slightly modified from Swift's similar code. """ def __init__(self, *args, **kwargs): self.timeout_seconds = kwargs.get('timeout', DEFAULT_SQL_CALL_TIMEOUT) kwargs['timeout'] = 0 sqlite3.Connection.__init__(self, *args, **kwargs) def _timeout(self, call): with timeout.Timeout(self.timeout_seconds): while True: try: return call() except sqlite3.OperationalError as e: if 'locked' not in str(e): raise sleep(0.05) def execute(self, *args, **kwargs): return self._timeout(lambda: sqlite3.Connection.execute( self, *args, **kwargs)) def commit(self): return self._timeout(lambda: sqlite3.Connection.commit(self)) def dict_factory(cur, row): return dict( ((col[0], row[idx]) for idx, col in enumerate(cur.description))) class Driver(base.Driver): """ Cache driver that uses xattr file tags and requires a filesystem that has atimes set. """ def configure(self): """ Configure the driver to use the stored configuration options Any store that needs special configuration should implement this method. If the store was not able to successfully configure itself, it should raise `exception.BadDriverConfiguration` """ super(Driver, self).configure() # Create the SQLite database that will hold our cache attributes self.initialize_db() def initialize_db(self): db = CONF.image_cache_sqlite_db self.db_path = os.path.join(self.base_dir, db) try: conn = sqlite3.connect(self.db_path, check_same_thread=False, factory=SqliteConnection) conn.executescript(""" CREATE TABLE IF NOT EXISTS cached_images ( image_id TEXT PRIMARY KEY, last_accessed REAL DEFAULT 0.0, last_modified REAL DEFAULT 0.0, size INTEGER DEFAULT 0, hits INTEGER DEFAULT 0, checksum TEXT ); """) conn.close() except sqlite3.DatabaseError as e: msg = _("Failed to initialize the image cache database. " "Got error: %s") % e LOG.error(msg) raise exception.BadDriverConfiguration(driver_name='sqlite', reason=msg) def get_cache_size(self): """ Returns the total size in bytes of the image cache. """ sizes = [] for path in self.get_cache_files(self.base_dir): if path == self.db_path: continue file_info = os.stat(path) sizes.append(file_info[stat.ST_SIZE]) return sum(sizes) def get_hit_count(self, image_id): """ Return the number of hits that an image has. :param image_id: Opaque image identifier """ if not self.is_cached(image_id): return 0 hits = 0 with self.get_db() as db: cur = db.execute("""SELECT hits FROM cached_images WHERE image_id = ?""", (image_id,)) hits = cur.fetchone()[0] return hits def get_cached_images(self): """ Returns a list of records about cached images. """ LOG.debug(_("Gathering cached image entries.")) with self.get_db() as db: cur = db.execute("""SELECT image_id, hits, last_accessed, last_modified, size FROM cached_images ORDER BY image_id""") cur.row_factory = dict_factory return [r for r in cur] def is_cached(self, image_id): """ Returns True if the image with the supplied ID has its image file cached. :param image_id: Image ID """ return os.path.exists(self.get_image_filepath(image_id)) def is_cacheable(self, image_id): """ Returns True if the image with the supplied ID can have its image file cached, False otherwise. :param image_id: Image ID """ # Make sure we're not already cached or caching the image return not (self.is_cached(image_id) or self.is_being_cached(image_id)) def is_being_cached(self, image_id): """ Returns True if the image with supplied id is currently in the process of having its image file cached. :param image_id: Image ID """ path = self.get_image_filepath(image_id, 'incomplete') return os.path.exists(path) def is_queued(self, image_id): """ Returns True if the image identifier is in our cache queue. :param image_id: Image ID """ path = self.get_image_filepath(image_id, 'queue') return os.path.exists(path) def delete_all_cached_images(self): """ Removes all cached image files and any attributes about the images """ deleted = 0 with self.get_db() as db: for path in self.get_cache_files(self.base_dir): delete_cached_file(path) deleted += 1 db.execute("""DELETE FROM cached_images""") db.commit() return deleted def delete_cached_image(self, image_id): """ Removes a specific cached image file and any attributes about the image :param image_id: Image ID """ path = self.get_image_filepath(image_id) with self.get_db() as db: delete_cached_file(path) db.execute("""DELETE FROM cached_images WHERE image_id = ?""", (image_id, )) db.commit() def delete_all_queued_images(self): """ Removes all queued image files and any attributes about the images """ files = [f for f in self.get_cache_files(self.queue_dir)] for file in files: os.unlink(file) return len(files) def delete_queued_image(self, image_id): """ Removes a specific queued image file and any attributes about the image :param image_id: Image ID """ path = self.get_image_filepath(image_id, 'queue') if os.path.exists(path): os.unlink(path) def clean(self, stall_time=None): """ Delete any image files in the invalid directory and any files in the incomplete directory that are older than a configurable amount of time. """ self.delete_invalid_files() if stall_time is None: stall_time = CONF.image_cache_stall_time now = time.time() older_than = now - stall_time self.delete_stalled_files(older_than) def get_least_recently_accessed(self): """ Return a tuple containing the image_id and size of the least recently accessed cached file, or None if no cached files. """ with self.get_db() as db: cur = db.execute("""SELECT image_id FROM cached_images ORDER BY last_accessed LIMIT 1""") try: image_id = cur.fetchone()[0] except TypeError: # There are no more cached images return None path = self.get_image_filepath(image_id) try: file_info = os.stat(path) size = file_info[stat.ST_SIZE] except OSError: size = 0 return image_id, size @contextmanager def open_for_write(self, image_id): """ Open a file for writing the image file for an image with supplied identifier. :param image_id: Image ID """ incomplete_path = self.get_image_filepath(image_id, 'incomplete') def commit(): with self.get_db() as db: final_path = self.get_image_filepath(image_id) LOG.debug(_("Fetch finished, moving " "'%(incomplete_path)s' to '%(final_path)s'"), dict(incomplete_path=incomplete_path, final_path=final_path)) os.rename(incomplete_path, final_path) # Make sure that we "pop" the image from the queue... if self.is_queued(image_id): os.unlink(self.get_image_filepath(image_id, 'queue')) filesize = os.path.getsize(final_path) now = time.time() db.execute("""INSERT INTO cached_images (image_id, last_accessed, last_modified, hits, size) VALUES (?, 0, ?, 0, ?)""", (image_id, now, filesize)) db.commit() def rollback(e): with self.get_db() as db: if os.path.exists(incomplete_path): invalid_path = self.get_image_filepath(image_id, 'invalid') LOG.debug(_("Fetch of cache file failed (%(e)s), rolling " "back by moving '%(incomplete_path)s' to " "'%(invalid_path)s'"), {'e': e, 'incomplete_path': incomplete_path, 'invalid_path': invalid_path}) os.rename(incomplete_path, invalid_path) db.execute("""DELETE FROM cached_images WHERE image_id = ?""", (image_id, )) db.commit() try: with open(incomplete_path, 'wb') as cache_file: yield cache_file except Exception as e: rollback(e) raise else: commit() finally: # if the generator filling the cache file neither raises an # exception, nor completes fetching all data, neither rollback # nor commit will have been called, so the incomplete file # will persist - in that case remove it as it is unusable # example: ^c from client fetch if os.path.exists(incomplete_path): rollback('incomplete fetch') @contextmanager def open_for_read(self, image_id): """ Open and yield file for reading the image file for an image with supplied identifier. :param image_id: Image ID """ path = self.get_image_filepath(image_id) with open(path, 'rb') as cache_file: yield cache_file now = time.time() with self.get_db() as db: db.execute("""UPDATE cached_images SET hits = hits + 1, last_accessed = ? WHERE image_id = ?""", (now, image_id)) db.commit() @contextmanager def get_db(self): """ Returns a context manager that produces a database connection that self-closes and calls rollback if an error occurs while using the database connection """ conn = sqlite3.connect(self.db_path, check_same_thread=False, factory=SqliteConnection) conn.row_factory = sqlite3.Row conn.text_factory = str conn.execute('PRAGMA synchronous = NORMAL') conn.execute('PRAGMA count_changes = OFF') conn.execute('PRAGMA temp_store = MEMORY') try: yield conn except sqlite3.DatabaseError as e: msg = _("Error executing SQLite call. Got error: %s") % e LOG.error(msg) conn.rollback() finally: conn.close() def queue_image(self, image_id): """ This adds a image to be cache to the queue. If the image already exists in the queue or has already been cached, we return False, True otherwise :param image_id: Image ID """ if self.is_cached(image_id): msg = _("Not queueing image '%s'. Already cached.") % image_id LOG.warn(msg) return False if self.is_being_cached(image_id): msg = _("Not queueing image '%s'. Already being " "written to cache") % image_id LOG.warn(msg) return False if self.is_queued(image_id): msg = _("Not queueing image '%s'. Already queued.") % image_id LOG.warn(msg) return False path = self.get_image_filepath(image_id, 'queue') # Touch the file to add it to the queue with open(path, "w"): pass return True def delete_invalid_files(self): """ Removes any invalid cache entries """ for path in self.get_cache_files(self.invalid_dir): os.unlink(path) LOG.info(_("Removed invalid cache file %s"), path) def delete_stalled_files(self, older_than): """ Removes any incomplete cache entries older than a supplied modified time. :param older_than: Files written to on or before this timestemp will be deleted. """ for path in self.get_cache_files(self.incomplete_dir): if os.path.getmtime(path) < older_than: try: os.unlink(path) LOG.info(_("Removed stalled cache file %s"), path) except Exception as e: msg = (_("Failed to delete file %(path)s. " "Got error: %(e)s") % dict(path=path, e=e)) LOG.warn(msg) def get_queued_images(self): """ Returns a list of image IDs that are in the queue. The list should be sorted by the time the image ID was inserted into the queue. """ files = [f for f in self.get_cache_files(self.queue_dir)] items = [] for path in files: mtime = os.path.getmtime(path) items.append((mtime, os.path.basename(path))) items.sort() return [image_id for (mtime, image_id) in items] def get_cache_files(self, basepath): """ Returns cache files in the supplied directory :param basepath: Directory to look in for cache files """ for fname in os.listdir(basepath): path = os.path.join(basepath, fname) if path != self.db_path and os.path.isfile(path): yield path def delete_cached_file(path): if os.path.exists(path): LOG.debug(_("Deleting image cache file '%s'"), path) os.unlink(path) else: LOG.warn(_("Cached image file '%s' doesn't exist, unable to" " delete"), path) glance-2014.1/glance/image_cache/drivers/base.py0000664000175400017540000001462612323736226022607 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ Base attribute driver class """ import os.path from oslo.config import cfg from glance.common import exception from glance.common import utils import glance.openstack.common.log as logging LOG = logging.getLogger(__name__) CONF = cfg.CONF class Driver(object): def configure(self): """ Configure the driver to use the stored configuration options Any store that needs special configuration should implement this method. If the store was not able to successfully configure itself, it should raise `exception.BadDriverConfiguration` """ # Here we set up the various file-based image cache paths # that we need in order to find the files in different states # of cache management. self.set_paths() def set_paths(self): """ Creates all necessary directories under the base cache directory """ self.base_dir = CONF.image_cache_dir if self.base_dir is None: msg = _('Failed to read %s from config') % 'image_cache_dir' LOG.error(msg) driver = self.__class__.__module__ raise exception.BadDriverConfiguration(driver_name=driver, reason=msg) self.incomplete_dir = os.path.join(self.base_dir, 'incomplete') self.invalid_dir = os.path.join(self.base_dir, 'invalid') self.queue_dir = os.path.join(self.base_dir, 'queue') dirs = [self.incomplete_dir, self.invalid_dir, self.queue_dir] for path in dirs: utils.safe_mkdirs(path) def get_cache_size(self): """ Returns the total size in bytes of the image cache. """ raise NotImplementedError def get_cached_images(self): """ Returns a list of records about cached images. The list of records shall be ordered by image ID and shall look like:: [ { 'image_id': , 'hits': INTEGER, 'last_modified': ISO_TIMESTAMP, 'last_accessed': ISO_TIMESTAMP, 'size': INTEGER }, ... ] """ return NotImplementedError def is_cached(self, image_id): """ Returns True if the image with the supplied ID has its image file cached. :param image_id: Image ID """ raise NotImplementedError def is_cacheable(self, image_id): """ Returns True if the image with the supplied ID can have its image file cached, False otherwise. :param image_id: Image ID """ raise NotImplementedError def is_queued(self, image_id): """ Returns True if the image identifier is in our cache queue. :param image_id: Image ID """ raise NotImplementedError def delete_all_cached_images(self): """ Removes all cached image files and any attributes about the images and returns the number of cached image files that were deleted. """ raise NotImplementedError def delete_cached_image(self, image_id): """ Removes a specific cached image file and any attributes about the image :param image_id: Image ID """ raise NotImplementedError def delete_all_queued_images(self): """ Removes all queued image files and any attributes about the images and returns the number of queued image files that were deleted. """ raise NotImplementedError def delete_queued_image(self, image_id): """ Removes a specific queued image file and any attributes about the image :param image_id: Image ID """ raise NotImplementedError def queue_image(self, image_id): """ Puts an image identifier in a queue for caching. Return True on successful add to the queue, False otherwise... :param image_id: Image ID """ def clean(self, stall_time=None): """ Dependent on the driver, clean up and destroy any invalid or incomplete cached images """ raise NotImplementedError def get_least_recently_accessed(self): """ Return a tuple containing the image_id and size of the least recently accessed cached file, or None if no cached files. """ raise NotImplementedError def open_for_write(self, image_id): """ Open a file for writing the image file for an image with supplied identifier. :param image_id: Image ID """ raise NotImplementedError def open_for_read(self, image_id): """ Open and yield file for reading the image file for an image with supplied identifier. :param image_id: Image ID """ raise NotImplementedError def get_image_filepath(self, image_id, cache_status='active'): """ This crafts an absolute path to a specific entry :param image_id: Image ID :param cache_status: Status of the image in the cache """ if cache_status == 'active': return os.path.join(self.base_dir, str(image_id)) return os.path.join(self.base_dir, cache_status, str(image_id)) def get_image_size(self, image_id): """ Return the size of the image file for an image with supplied identifier. :param image_id: Image ID """ path = self.get_image_filepath(image_id) return os.path.getsize(path) def get_queued_images(self): """ Returns a list of image IDs that are in the queue. The list should be sorted by the time the image ID was inserted into the queue. """ raise NotImplementedError glance-2014.1/glance/image_cache/drivers/__init__.py0000664000175400017540000000000012323736226023411 0ustar jenkinsjenkins00000000000000glance-2014.1/glance/image_cache/base.py0000664000175400017540000000133512323736226021122 0ustar jenkinsjenkins00000000000000# Copyright 2012 Red Hat, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from glance.image_cache import ImageCache class CacheApp(object): def __init__(self): self.cache = ImageCache() glance-2014.1/glance/image_cache/pruner.py0000664000175400017540000000141612323736226021523 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ Prunes the Image Cache """ from glance.image_cache import base class Pruner(base.CacheApp): def run(self): self.cache.prune() glance-2014.1/glance/image_cache/client.py0000664000175400017540000001006112323736226021462 0ustar jenkinsjenkins00000000000000# Copyright 2012 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import os from glance.common import client as base_client from glance.common import exception import glance.openstack.common.jsonutils as json class CacheClient(base_client.BaseClient): DEFAULT_PORT = 9292 DEFAULT_DOC_ROOT = '/v1' def delete_cached_image(self, image_id): """ Delete a specified image from the cache """ self.do_request("DELETE", "/cached_images/%s" % image_id) return True def get_cached_images(self, **kwargs): """ Returns a list of images stored in the image cache. """ res = self.do_request("GET", "/cached_images") data = json.loads(res.read())['cached_images'] return data def get_queued_images(self, **kwargs): """ Returns a list of images queued for caching """ res = self.do_request("GET", "/queued_images") data = json.loads(res.read())['queued_images'] return data def delete_all_cached_images(self): """ Delete all cached images """ res = self.do_request("DELETE", "/cached_images") data = json.loads(res.read()) num_deleted = data['num_deleted'] return num_deleted def queue_image_for_caching(self, image_id): """ Queue an image for prefetching into cache """ self.do_request("PUT", "/queued_images/%s" % image_id) return True def delete_queued_image(self, image_id): """ Delete a specified image from the cache queue """ self.do_request("DELETE", "/queued_images/%s" % image_id) return True def delete_all_queued_images(self): """ Delete all queued images """ res = self.do_request("DELETE", "/queued_images") data = json.loads(res.read()) num_deleted = data['num_deleted'] return num_deleted def get_client(host, port=None, timeout=None, use_ssl=False, 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 = { '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) return CacheClient( host=host, port=port, timeout=timeout, use_ssl=use_ssl, auth_tok=auth_token or os.getenv('OS_TOKEN'), creds=creds, insecure=insecure) glance-2014.1/glance/image_cache/prefetcher.py0000664000175400017540000000537012323736226022342 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ Prefetches images into the Image Cache """ import eventlet from glance.common import exception from glance import context from glance.image_cache import base import glance.openstack.common.log as logging import glance.registry.client.v1.api as registry import glance.store LOG = logging.getLogger(__name__) class Prefetcher(base.CacheApp): def __init__(self): super(Prefetcher, self).__init__() registry.configure_registry_client() registry.configure_registry_admin_creds() def fetch_image_into_cache(self, image_id): ctx = context.RequestContext(is_admin=True, show_deleted=True) try: image_meta = registry.get_image_metadata(ctx, image_id) if image_meta['status'] != 'active': LOG.warn(_("Image '%s' is not active. Not caching."), image_id) return False except exception.NotFound: LOG.warn(_("No metadata found for image '%s'"), image_id) return False location = image_meta['location'] image_data, image_size = glance.store.get_from_backend(ctx, location) LOG.debug(_("Caching image '%s'"), image_id) cache_tee_iter = self.cache.cache_tee_iter(image_id, image_data, image_meta['checksum']) # Image is tee'd into cache and checksum verified # as we iterate list(cache_tee_iter) return True def run(self): images = self.cache.get_queued_images() if not images: LOG.debug(_("Nothing to prefetch.")) return True num_images = len(images) LOG.debug(_("Found %d images to prefetch"), num_images) pool = eventlet.GreenPool(num_images) results = pool.imap(self.fetch_image_into_cache, images) successes = sum([1 for r in results if r is True]) if successes != num_images: LOG.error(_("Failed to successfully cache all " "images in queue.")) return False LOG.info(_("Successfully cached all %d images"), num_images) return True glance-2014.1/glance/image_cache/__init__.py0000664000175400017540000002712612323736230021750 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ LRU Cache for Image Data """ import hashlib from oslo.config import cfg from glance.common import exception from glance.common import utils from glance.openstack.common import importutils import glance.openstack.common.log as logging from glance.openstack.common import units LOG = logging.getLogger(__name__) image_cache_opts = [ cfg.StrOpt('image_cache_driver', default='sqlite', help=_('The driver to use for image cache management.')), cfg.IntOpt('image_cache_max_size', default=10 * units.Gi, # 10 GB help=_('The maximum size in bytes that the cache can use.')), cfg.IntOpt('image_cache_stall_time', default=86400, # 24 hours help=_('The amount of time to let an image remain in the ' 'cache without being accessed.')), cfg.StrOpt('image_cache_dir', help=_('Base directory that the Image Cache uses.')), ] CONF = cfg.CONF CONF.register_opts(image_cache_opts) class ImageCache(object): """Provides an LRU cache for image data.""" def __init__(self): self.init_driver() def init_driver(self): """ Create the driver for the cache """ driver_name = CONF.image_cache_driver driver_module = (__name__ + '.drivers.' + driver_name + '.Driver') try: self.driver_class = importutils.import_class(driver_module) LOG.info(_("Image cache loaded driver '%s'.") % driver_name) except ImportError as import_err: LOG.warn(_("Image cache driver " "'%(driver_name)s' failed to load. " "Got error: '%(import_err)s."), {'driver_name': driver_name, 'import_err': import_err}) driver_module = __name__ + '.drivers.sqlite.Driver' LOG.info(_("Defaulting to SQLite driver.")) self.driver_class = importutils.import_class(driver_module) self.configure_driver() def configure_driver(self): """ Configure the driver for the cache and, if it fails to configure, fall back to using the SQLite driver which has no odd dependencies """ try: self.driver = self.driver_class() self.driver.configure() except exception.BadDriverConfiguration as config_err: driver_module = self.driver_class.__module__ LOG.warn(_("Image cache driver " "'%(driver_module)s' failed to configure. " "Got error: '%(config_err)s"), {'driver_module': driver_module, 'config_err': config_err}) LOG.info(_("Defaulting to SQLite driver.")) default_module = __name__ + '.drivers.sqlite.Driver' self.driver_class = importutils.import_class(default_module) self.driver = self.driver_class() self.driver.configure() def is_cached(self, image_id): """ Returns True if the image with the supplied ID has its image file cached. :param image_id: Image ID """ return self.driver.is_cached(image_id) def is_queued(self, image_id): """ Returns True if the image identifier is in our cache queue. :param image_id: Image ID """ return self.driver.is_queued(image_id) def get_cache_size(self): """ Returns the total size in bytes of the image cache. """ return self.driver.get_cache_size() def get_hit_count(self, image_id): """ Return the number of hits that an image has :param image_id: Opaque image identifier """ return self.driver.get_hit_count(image_id) def get_cached_images(self): """ Returns a list of records about cached images. """ return self.driver.get_cached_images() def delete_all_cached_images(self): """ Removes all cached image files and any attributes about the images and returns the number of cached image files that were deleted. """ return self.driver.delete_all_cached_images() def delete_cached_image(self, image_id): """ Removes a specific cached image file and any attributes about the image :param image_id: Image ID """ self.driver.delete_cached_image(image_id) def delete_all_queued_images(self): """ Removes all queued image files and any attributes about the images and returns the number of queued image files that were deleted. """ return self.driver.delete_all_queued_images() def delete_queued_image(self, image_id): """ Removes a specific queued image file and any attributes about the image :param image_id: Image ID """ self.driver.delete_queued_image(image_id) def prune(self): """ Removes all cached image files above the cache's maximum size. Returns a tuple containing the total number of cached files removed and the total size of all pruned image files. """ max_size = CONF.image_cache_max_size current_size = self.driver.get_cache_size() if max_size > current_size: LOG.debug(_("Image cache has free space, skipping prune...")) return (0, 0) overage = current_size - max_size LOG.debug(_("Image cache currently %(overage)d bytes over max " "size. Starting prune to max size of %(max_size)d "), {'overage': overage, 'max_size': max_size}) total_bytes_pruned = 0 total_files_pruned = 0 entry = self.driver.get_least_recently_accessed() while entry and current_size > max_size: image_id, size = entry LOG.debug(_("Pruning '%(image_id)s' to free %(size)d bytes"), {'image_id': image_id, 'size': size}) self.driver.delete_cached_image(image_id) total_bytes_pruned = total_bytes_pruned + size total_files_pruned = total_files_pruned + 1 current_size = current_size - size entry = self.driver.get_least_recently_accessed() LOG.debug(_("Pruning finished pruning. " "Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d."), {'total_files_pruned': total_files_pruned, 'total_bytes_pruned': total_bytes_pruned}) return total_files_pruned, total_bytes_pruned def clean(self, stall_time=None): """ Cleans up any invalid or incomplete cached images. The cache driver decides what that means... """ self.driver.clean(stall_time) def queue_image(self, image_id): """ This adds a image to be cache to the queue. If the image already exists in the queue or has already been cached, we return False, True otherwise :param image_id: Image ID """ return self.driver.queue_image(image_id) def get_caching_iter(self, image_id, image_checksum, image_iter): """ Returns an iterator that caches the contents of an image while the image contents are read through the supplied iterator. :param image_id: Image ID :param image_checksum: checksum expected to be generated while iterating over image data :param image_iter: Iterator that will read image contents """ if not self.driver.is_cacheable(image_id): return image_iter LOG.debug(_("Tee'ing image '%s' into cache"), image_id) return self.cache_tee_iter(image_id, image_iter, image_checksum) def cache_tee_iter(self, image_id, image_iter, image_checksum): try: current_checksum = hashlib.md5() with self.driver.open_for_write(image_id) as cache_file: for chunk in image_iter: try: cache_file.write(chunk) finally: current_checksum.update(chunk) yield chunk cache_file.flush() if (image_checksum and image_checksum != current_checksum.hexdigest()): msg = _("Checksum verification failed. Aborted " "caching of image '%s'.") % image_id raise exception.GlanceException(msg) except exception.GlanceException as e: # image_iter has given us bad, (size_checked_iter has found a # bad length), or corrupt data (checksum is wrong). LOG.exception(e) raise except Exception as e: LOG.exception(_("Exception encountered while tee'ing " "image '%(image_id)s' into cache: %(error)s. " "Continuing with response.") % {'image_id': image_id, 'error': e}) # If no checksum provided continue responding even if # caching failed. for chunk in image_iter: yield chunk def cache_image_iter(self, image_id, image_iter, image_checksum=None): """ Cache an image with supplied iterator. :param image_id: Image ID :param image_file: Iterator retrieving image chunks :param image_checksum: Checksum of image :retval True if image file was cached, False otherwise """ if not self.driver.is_cacheable(image_id): return False for chunk in self.get_caching_iter(image_id, image_checksum, image_iter): pass return True def cache_image_file(self, image_id, image_file): """ Cache an image file. :param image_id: Image ID :param image_file: Image file to cache :retval True if image file was cached, False otherwise """ CHUNKSIZE = 64 * units.Mi return self.cache_image_iter(image_id, utils.chunkiter(image_file, CHUNKSIZE)) def open_for_read(self, image_id): """ Open and yield file for reading the image file for an image with supplied identifier. :note Upon successful reading of the image file, the image's hit count will be incremented. :param image_id: Image ID """ return self.driver.open_for_read(image_id) def get_image_size(self, image_id): """ Return the size of the image file for an image with supplied identifier. :param image_id: Image ID """ return self.driver.get_image_size(image_id) def get_queued_images(self): """ Returns a list of image IDs that are in the queue. The list should be sorted by the time the image ID was inserted into the queue. """ return self.driver.get_queued_images() glance-2014.1/glance/tests/0000775000175400017540000000000012323736427016574 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/tests/unit/0000775000175400017540000000000012323736427017553 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/tests/unit/test_versions.py0000664000175400017540000001121612323736226023032 0ustar jenkinsjenkins00000000000000# Copyright 2012 OpenStack Foundation. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import webob from glance.api.middleware import version_negotiation from glance.api import versions from glance.openstack.common import jsonutils from glance.tests.unit import base class VersionsTest(base.IsolatedUnitTest): """Test the version information returned from the API service.""" def test_get_version_list(self): req = webob.Request.blank('/', base_url='http://127.0.0.1:9292/') req.accept = 'application/json' self.config(bind_host='127.0.0.1', bind_port=9292) res = versions.Controller().index(req) self.assertEqual(res.status_int, 300) self.assertEqual(res.content_type, 'application/json') results = jsonutils.loads(res.body)['versions'] expected = [ { 'id': 'v2.2', 'status': 'CURRENT', 'links': [{'rel': 'self', 'href': 'http://127.0.0.1:9292/v2/'}], }, { 'id': 'v2.1', 'status': 'SUPPORTED', 'links': [{'rel': 'self', 'href': 'http://127.0.0.1:9292/v2/'}], }, { 'id': 'v2.0', 'status': 'SUPPORTED', 'links': [{'rel': 'self', 'href': 'http://127.0.0.1:9292/v2/'}], }, { 'id': 'v1.1', 'status': 'CURRENT', 'links': [{'rel': 'self', 'href': 'http://127.0.0.1:9292/v1/'}], }, { 'id': 'v1.0', 'status': 'SUPPORTED', 'links': [{'rel': 'self', 'href': 'http://127.0.0.1:9292/v1/'}], }, ] self.assertEqual(results, expected) class VersionNegotiationTest(base.IsolatedUnitTest): def setUp(self): super(VersionNegotiationTest, self).setUp() self.middleware = version_negotiation.VersionNegotiationFilter(None) def test_request_url_v1(self): request = webob.Request.blank('/v1/images') self.middleware.process_request(request) self.assertEqual('/v1/images', request.path_info) def test_request_url_v1_0(self): request = webob.Request.blank('/v1.0/images') self.middleware.process_request(request) self.assertEqual('/v1/images', request.path_info) def test_request_url_v1_1(self): request = webob.Request.blank('/v1.1/images') self.middleware.process_request(request) self.assertEqual('/v1/images', request.path_info) def test_request_accept_v1(self): request = webob.Request.blank('/images') request.headers = {'accept': 'application/vnd.openstack.images-v1'} self.middleware.process_request(request) self.assertEqual('/v1/images', request.path_info) def test_request_url_v2(self): request = webob.Request.blank('/v2/images') self.middleware.process_request(request) self.assertEqual('/v2/images', request.path_info) def test_request_url_v2_0(self): request = webob.Request.blank('/v2.0/images') self.middleware.process_request(request) self.assertEqual('/v2/images', request.path_info) def test_request_url_v2_1(self): request = webob.Request.blank('/v2.1/images') self.middleware.process_request(request) self.assertEqual('/v2/images', request.path_info) def test_request_url_v2_2(self): request = webob.Request.blank('/v2.2/images') self.middleware.process_request(request) self.assertEqual('/v2/images', request.path_info) def test_request_url_v2_3_unsupported(self): request = webob.Request.blank('/v2.3/images') resp = self.middleware.process_request(request) self.assertIsInstance(resp, versions.Controller) def test_request_url_v3_unsupported(self): request = webob.Request.blank('/v3/images') resp = self.middleware.process_request(request) self.assertIsInstance(resp, versions.Controller) glance-2014.1/glance/tests/unit/test_glance_replicator.py0000664000175400017540000005252012323736226024642 0ustar jenkinsjenkins00000000000000# Copyright 2012 Michael Still and Canonical Inc # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import copy import os import sys import UserDict import uuid import fixtures import six from glance.cmd import replicator as glance_replicator from glance.openstack.common import jsonutils from glance.tests import utils as test_utils IMG_RESPONSE_ACTIVE = { 'content-length': '0', 'property-image_state': 'available', 'min_ram': '0', 'disk_format': 'aki', 'updated_at': '2012-06-25T02:10:36', 'date': 'Thu, 28 Jun 2012 07:20:05 GMT', 'owner': '8aef75b5c0074a59aa99188fdb4b9e90', 'id': '6d55dd55-053a-4765-b7bc-b30df0ea3861', 'size': '4660272', 'property-image_location': 'ubuntu-bucket/oneiric-server-cloudimg-amd64-' 'vmlinuz-generic.manifest.xml', 'property-architecture': 'x86_64', 'etag': 'f46cfe7fb3acaff49a3567031b9b53bb', 'location': 'http://127.0.0.1:9292/v1/images/' '6d55dd55-053a-4765-b7bc-b30df0ea3861', 'container_format': 'aki', 'status': 'active', 'deleted': 'False', 'min_disk': '0', 'is_public': 'False', 'name': 'ubuntu-bucket/oneiric-server-cloudimg-amd64-vmlinuz-generic', 'checksum': 'f46cfe7fb3acaff49a3567031b9b53bb', 'created_at': '2012-06-25T02:10:32', 'protected': 'False', 'content-type': 'text/html; charset=UTF-8' } IMG_RESPONSE_QUEUED = copy.copy(IMG_RESPONSE_ACTIVE) IMG_RESPONSE_QUEUED['status'] = 'queued' IMG_RESPONSE_QUEUED['id'] = '49b2c782-ee10-4692-84f8-3942e9432c4b' IMG_RESPONSE_QUEUED['location'] = ('http://127.0.0.1:9292/v1/images/' + IMG_RESPONSE_QUEUED['id']) class FakeHTTPConnection(object): def __init__(self): self.count = 0 self.reqs = {} self.last_req = None self.host = 'localhost' self.port = 9292 def prime_request(self, method, url, in_body, in_headers, out_code, out_body, out_headers): if not url.startswith('/'): url = '/' + url hkeys = in_headers.keys() hkeys.sort() hashable = (method, url, in_body, ' '.join(hkeys)) flat_headers = [] for key in out_headers: flat_headers.append((key, out_headers[key])) self.reqs[hashable] = (out_code, out_body, flat_headers) def request(self, method, url, body, headers): self.count += 1 hkeys = headers.keys() hkeys.sort() hashable = (method, url, body, ' '.join(hkeys)) if hashable not in self.reqs: options = [] for h in self.reqs: options.append(repr(h)) raise Exception('No such primed request: %s "%s"\n' '%s\n\n' 'Available:\n' '%s' % (method, url, hashable, '\n\n'.join(options))) self.last_req = hashable def getresponse(self): class FakeResponse(object): def __init__(self, (code, body, headers)): self.body = six.StringIO(body) self.headers = headers self.status = code def read(self, count=1000000): return self.body.read(count) def getheaders(self): return self.headers return FakeResponse(self.reqs[self.last_req]) class ImageServiceTestCase(test_utils.BaseTestCase): def test_rest_errors(self): c = glance_replicator.ImageService(FakeHTTPConnection(), 'noauth') for code, exc in [(400, glance_replicator.ServerErrorException), (401, glance_replicator.AuthenticationException), (403, glance_replicator.AuthenticationException), (409, glance_replicator.ImageAlreadyPresentException), (500, glance_replicator.ServerErrorException)]: c.conn.prime_request('GET', ('v1/images/' '5dcddce0-cba5-4f18-9cf4-9853c7b207a6'), '', {'x-auth-token': 'noauth'}, code, '', {}) self.assertRaises(exc, c.get_image, '5dcddce0-cba5-4f18-9cf4-9853c7b207a6') def test_rest_get_images(self): c = glance_replicator.ImageService(FakeHTTPConnection(), 'noauth') # Two images, one of which is queued resp = {'images': [IMG_RESPONSE_ACTIVE, IMG_RESPONSE_QUEUED]} c.conn.prime_request('GET', 'v1/images/detail?is_public=None', '', {'x-auth-token': 'noauth'}, 200, jsonutils.dumps(resp), {}) c.conn.prime_request('GET', ('v1/images/detail?marker=%s&is_public=None' % IMG_RESPONSE_QUEUED['id']), '', {'x-auth-token': 'noauth'}, 200, jsonutils.dumps({'images': []}), {}) imgs = list(c.get_images()) self.assertEqual(len(imgs), 2) self.assertEqual(c.conn.count, 2) def test_rest_get_image(self): c = glance_replicator.ImageService(FakeHTTPConnection(), 'noauth') image_contents = 'THISISTHEIMAGEBODY' c.conn.prime_request('GET', 'v1/images/%s' % IMG_RESPONSE_ACTIVE['id'], '', {'x-auth-token': 'noauth'}, 200, image_contents, IMG_RESPONSE_ACTIVE) body = c.get_image(IMG_RESPONSE_ACTIVE['id']) self.assertEqual(body.read(), image_contents) def test_rest_header_list_to_dict(self): i = [('x-image-meta-banana', 42), ('gerkin', 12), ('x-image-meta-property-frog', 11), ('x-image-meta-property-duck', 12)] o = glance_replicator.ImageService._header_list_to_dict(i) self.assertTrue('banana' in o) self.assertTrue('gerkin' in o) self.assertTrue('properties' in o) self.assertTrue('frog' in o['properties']) self.assertTrue('duck' in o['properties']) self.assertFalse('x-image-meta-banana' in o) def test_rest_get_image_meta(self): c = glance_replicator.ImageService(FakeHTTPConnection(), 'noauth') c.conn.prime_request('HEAD', 'v1/images/%s' % IMG_RESPONSE_ACTIVE['id'], '', {'x-auth-token': 'noauth'}, 200, '', IMG_RESPONSE_ACTIVE) header = c.get_image_meta(IMG_RESPONSE_ACTIVE['id']) self.assertTrue('id' in header) def test_rest_dict_to_headers(self): i = {'banana': 42, 'gerkin': 12, 'properties': {'frog': 1, 'kernel_id': None} } o = glance_replicator.ImageService._dict_to_headers(i) self.assertTrue('x-image-meta-banana' in o) self.assertTrue('x-image-meta-gerkin' in o) self.assertTrue('x-image-meta-property-frog' in o) self.assertTrue('x-image-meta-property-kernel_id' in o) self.assertEqual(o['x-image-meta-property-kernel_id'], '') self.assertFalse('properties' in o) def test_rest_add_image(self): c = glance_replicator.ImageService(FakeHTTPConnection(), 'noauth') image_body = 'THISISANIMAGEBODYFORSURE!' image_meta_with_proto = {} image_meta_with_proto['x-auth-token'] = 'noauth' image_meta_with_proto['Content-Type'] = 'application/octet-stream' image_meta_with_proto['Content-Length'] = len(image_body) for key in IMG_RESPONSE_ACTIVE: image_meta_with_proto['x-image-meta-%s' % key] = \ IMG_RESPONSE_ACTIVE[key] c.conn.prime_request('POST', 'v1/images', image_body, image_meta_with_proto, 200, '', IMG_RESPONSE_ACTIVE) headers, body = c.add_image(IMG_RESPONSE_ACTIVE, image_body) self.assertEqual(headers, IMG_RESPONSE_ACTIVE) self.assertEqual(c.conn.count, 1) def test_rest_add_image_meta(self): c = glance_replicator.ImageService(FakeHTTPConnection(), 'noauth') image_meta = {'id': '5dcddce0-cba5-4f18-9cf4-9853c7b207a6'} image_meta_headers = \ glance_replicator.ImageService._dict_to_headers(image_meta) image_meta_headers['x-auth-token'] = 'noauth' image_meta_headers['Content-Type'] = 'application/octet-stream' c.conn.prime_request('PUT', 'v1/images/%s' % image_meta['id'], '', image_meta_headers, 200, '', '') headers, body = c.add_image_meta(image_meta) class FakeHttpResponse(object): def __init__(self, headers, data): self.headers = headers self.data = six.StringIO(data) def getheaders(self): return self.headers def read(self, amt=None): return self.data.read(amt) FAKEIMAGES = [{'status': 'active', 'size': 100, 'dontrepl': 'banana', 'id': '5dcddce0-cba5-4f18-9cf4-9853c7b207a6'}, {'status': 'deleted', 'size': 200, 'dontrepl': 'banana', 'id': 'f4da1d2a-40e8-4710-b3aa-0222a4cc887b'}, {'status': 'active', 'size': 300, 'dontrepl': 'banana', 'id': '37ff82db-afca-48c7-ae0b-ddc7cf83e3db'}] FAKEIMAGES_LIVEMASTER = [{'status': 'active', 'size': 100, 'dontrepl': 'banana', 'id': '5dcddce0-cba5-4f18-9cf4-9853c7b207a6'}, {'status': 'deleted', 'size': 200, 'dontrepl': 'banana', 'id': 'f4da1d2a-40e8-4710-b3aa-0222a4cc887b'}, {'status': 'deleted', 'size': 300, 'dontrepl': 'banana', 'id': '37ff82db-afca-48c7-ae0b-ddc7cf83e3db'}, {'status': 'active', 'size': 100, 'dontrepl': 'banana', 'id': '15648dd7-8dd0-401c-bd51-550e1ba9a088'}] class FakeImageService(object): def __init__(self, http_conn, authtoken): self.authtoken = authtoken def get_images(self): if self.authtoken == 'livemastertoken': return FAKEIMAGES_LIVEMASTER return FAKEIMAGES def get_image(self, id): return FakeHttpResponse({}, 'data') def get_image_meta(self, id): for img in FAKEIMAGES: if img['id'] == id: return img return {} def add_image_meta(self, meta): return {'status': 200}, None def add_image(self, meta, data): return {'status': 200}, None def get_image_service(): return FakeImageService def check_no_args(command, args): options = UserDict.UserDict() no_args_error = False orig_img_service = glance_replicator.get_image_service try: glance_replicator.get_image_service = get_image_service command(options, args) except TypeError: no_args_error = True finally: glance_replicator.get_image_service = orig_img_service return no_args_error def check_bad_args(command, args): options = UserDict.UserDict() bad_args_error = False orig_img_service = glance_replicator.get_image_service try: glance_replicator.get_image_service = get_image_service command(options, args) except ValueError: bad_args_error = True finally: glance_replicator.get_image_service = orig_img_service return bad_args_error class ReplicationCommandsTestCase(test_utils.BaseTestCase): def test_replication_size(self): options = UserDict.UserDict() options.slavetoken = 'slavetoken' args = ['localhost:9292'] stdout = sys.stdout orig_img_service = glance_replicator.get_image_service sys.stdout = six.StringIO() try: glance_replicator.get_image_service = get_image_service glance_replicator.replication_size(options, args) sys.stdout.seek(0) output = sys.stdout.read() finally: sys.stdout = stdout glance_replicator.get_image_service = orig_img_service output = output.rstrip() self.assertEqual(output, 'Total size is 400 bytes across 2 images') def test_replication_size_with_no_args(self): args = [] command = glance_replicator.replication_size self.assertTrue(check_no_args(command, args)) def test_replication_size_with_bad_args(self): args = ['aaa'] command = glance_replicator.replication_size self.assertTrue(check_bad_args(command, args)) def test_replication_dump(self): tempdir = self.useFixture(fixtures.TempDir()).path options = UserDict.UserDict() options.chunksize = 4096 options.mastertoken = 'mastertoken' options.metaonly = False args = ['localhost:9292', tempdir] orig_img_service = glance_replicator.get_image_service self.addCleanup(setattr, glance_replicator, 'get_image_service', orig_img_service) glance_replicator.get_image_service = get_image_service glance_replicator.replication_dump(options, args) for active in ['5dcddce0-cba5-4f18-9cf4-9853c7b207a6', '37ff82db-afca-48c7-ae0b-ddc7cf83e3db']: imgfile = os.path.join(tempdir, active) self.assertTrue(os.path.exists(imgfile)) self.assertTrue(os.path.exists('%s.img' % imgfile)) with open(imgfile) as f: d = jsonutils.loads(f.read()) self.assertTrue('status' in d) self.assertTrue('id' in d) self.assertTrue('size' in d) for inactive in ['f4da1d2a-40e8-4710-b3aa-0222a4cc887b']: imgfile = os.path.join(tempdir, inactive) self.assertTrue(os.path.exists(imgfile)) self.assertFalse(os.path.exists('%s.img' % imgfile)) with open(imgfile) as f: d = jsonutils.loads(f.read()) self.assertTrue('status' in d) self.assertTrue('id' in d) self.assertTrue('size' in d) def test_replication_dump_with_no_args(self): args = [] command = glance_replicator.replication_dump self.assertTrue(check_no_args(command, args)) def test_replication_dump_with_bad_args(self): args = ['aaa', 'bbb'] command = glance_replicator.replication_dump self.assertTrue(check_bad_args(command, args)) def test_replication_load(self): tempdir = self.useFixture(fixtures.TempDir()).path def write_image(img, data): imgfile = os.path.join(tempdir, img['id']) with open(imgfile, 'w') as f: f.write(jsonutils.dumps(img)) if data: with open('%s.img' % imgfile, 'w') as f: f.write(data) for img in FAKEIMAGES: cimg = copy.copy(img) # We need at least one image where the stashed metadata on disk # is newer than what the fake has if cimg['id'] == '5dcddce0-cba5-4f18-9cf4-9853c7b207a6': cimg['extra'] = 'thisissomeextra' # This is an image where the metadata change should be ignored if cimg['id'] == 'f4da1d2a-40e8-4710-b3aa-0222a4cc887b': cimg['dontrepl'] = 'thisisyetmoreextra' write_image(cimg, 'kjdhfkjshdfkjhsdkfd') # And an image which isn't on the destination at all new_id = str(uuid.uuid4()) cimg['id'] = new_id write_image(cimg, 'dskjfhskjhfkfdhksjdhf') # And an image which isn't on the destination, but lacks image # data new_id_missing_data = str(uuid.uuid4()) cimg['id'] = new_id_missing_data write_image(cimg, None) # A file which should be ignored badfile = os.path.join(tempdir, 'kjdfhf') with open(badfile, 'w') as f: f.write(jsonutils.dumps([1, 2, 3, 4, 5])) # Finally, we're ready to test options = UserDict.UserDict() options.dontreplicate = 'dontrepl dontreplabsent' options.slavetoken = 'slavetoken' args = ['localhost:9292', tempdir] orig_img_service = glance_replicator.get_image_service try: glance_replicator.get_image_service = get_image_service updated = glance_replicator.replication_load(options, args) finally: glance_replicator.get_image_service = orig_img_service self.assertTrue('5dcddce0-cba5-4f18-9cf4-9853c7b207a6' in updated) self.assertFalse('f4da1d2a-40e8-4710-b3aa-0222a4cc887b' in updated) self.assertTrue(new_id in updated) self.assertFalse(new_id_missing_data in updated) def test_replication_load_with_no_args(self): args = [] command = glance_replicator.replication_load self.assertTrue(check_no_args(command, args)) def test_replication_load_with_bad_args(self): args = ['aaa', 'bbb'] command = glance_replicator.replication_load self.assertTrue(check_bad_args(command, args)) def test_replication_livecopy(self): options = UserDict.UserDict() options.chunksize = 4096 options.dontreplicate = 'dontrepl dontreplabsent' options.mastertoken = 'livemastertoken' options.slavetoken = 'liveslavetoken' options.metaonly = False args = ['localhost:9292', 'localhost:9393'] orig_img_service = glance_replicator.get_image_service try: glance_replicator.get_image_service = get_image_service updated = glance_replicator.replication_livecopy(options, args) finally: glance_replicator.get_image_service = orig_img_service self.assertEqual(len(updated), 2) def test_replication_livecopy_with_no_args(self): args = [] command = glance_replicator.replication_livecopy self.assertTrue(check_no_args(command, args)) def test_replication_livecopy_with_bad_args(self): args = ['aaa', 'bbb'] command = glance_replicator.replication_livecopy self.assertTrue(check_bad_args(command, args)) def test_replication_compare(self): options = UserDict.UserDict() options.chunksize = 4096 options.dontreplicate = 'dontrepl dontreplabsent' options.mastertoken = 'livemastertoken' options.slavetoken = 'liveslavetoken' options.metaonly = False args = ['localhost:9292', 'localhost:9393'] orig_img_service = glance_replicator.get_image_service try: glance_replicator.get_image_service = get_image_service differences = glance_replicator.replication_compare(options, args) finally: glance_replicator.get_image_service = orig_img_service self.assertTrue('15648dd7-8dd0-401c-bd51-550e1ba9a088' in differences) self.assertEqual(differences['15648dd7-8dd0-401c-bd51-550e1ba9a088'], 'missing') self.assertTrue('37ff82db-afca-48c7-ae0b-ddc7cf83e3db' in differences) self.assertEqual(differences['37ff82db-afca-48c7-ae0b-ddc7cf83e3db'], 'diff') def test_replication_compare_with_no_args(self): args = [] command = glance_replicator.replication_compare self.assertTrue(check_no_args(command, args)) def test_replication_compare_with_bad_args(self): args = ['aaa', 'bbb'] command = glance_replicator.replication_compare self.assertTrue(check_bad_args(command, args)) class ReplicationUtilitiesTestCase(test_utils.BaseTestCase): def test_check_upload_response_headers(self): glance_replicator._check_upload_response_headers({'status': 'active'}, None) d = {'image': {'status': 'active'}} glance_replicator._check_upload_response_headers({}, jsonutils.dumps(d)) self.assertRaises( glance_replicator.UploadException, glance_replicator._check_upload_response_headers, {}, None) def test_image_present(self): client = FakeImageService(None, 'noauth') self.assertTrue(glance_replicator._image_present( client, '5dcddce0-cba5-4f18-9cf4-9853c7b207a6')) self.assertFalse(glance_replicator._image_present( client, uuid.uuid4())) def test_dict_diff(self): a = {'a': 1, 'b': 2, 'c': 3} b = {'a': 1, 'b': 2} c = {'a': 1, 'b': 1, 'c': 3} d = {'a': 1, 'b': 2, 'c': 3, 'd': 4} # Only things that the first dict has which the second dict doesn't # matter here. self.assertFalse(glance_replicator._dict_diff(a, a)) self.assertTrue(glance_replicator._dict_diff(a, b)) self.assertTrue(glance_replicator._dict_diff(a, c)) self.assertFalse(glance_replicator._dict_diff(a, d)) glance-2014.1/glance/tests/unit/test_manage.py0000664000175400017540000002257512323736226022424 0ustar jenkinsjenkins00000000000000# Copyright 2014 Rackspace Hosting # 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 fixtures import mock import testtools import glance from glance.cmd import manage from glance.db import migration as db_migration from glance.db.sqlalchemy import api as db_api from glance.openstack.common.db.sqlalchemy import migration class TestManageBase(testtools.TestCase): def setUp(self): super(TestManageBase, self).setUp() def clear_conf(): manage.CONF.reset() manage.CONF.unregister_opt(manage.command_opt) manage.CONF.db_enforce_mysql_charset = True self.addCleanup(clear_conf) self.patcher = mock.patch('glance.db.sqlalchemy.api.get_engine') self.patcher.start() self.addCleanup(self.patcher.stop) def _main_test_helper(self, argv, func_name=None, *exp_args, **exp_kwargs): self.useFixture(fixtures.MonkeyPatch('sys.argv', argv)) manage.main() func_name.assert_called_once_with(*exp_args, **exp_kwargs) class TestLegacyManage(TestManageBase): def test_legacy_db_version(self): migration.db_version = mock.Mock() self._main_test_helper(['glance.cmd.manage', 'db_version'], glance.openstack.common.db.sqlalchemy. migration.db_version, db_api.get_engine(), db_migration.MIGRATE_REPO_PATH, 0) def test_legacy_db_sync(self): migration.db_sync = mock.Mock() self._main_test_helper(['glance.cmd.manage', 'db_sync'], glance.openstack.common.db.sqlalchemy. migration.db_sync, db_api.get_engine(), db_migration.MIGRATE_REPO_PATH, None, sanity_check=True) def test_legacy_db_upgrade(self): migration.db_sync = mock.Mock() self._main_test_helper(['glance.cmd.manage', 'db_upgrade'], migration.db_sync, db_api.get_engine(), db_migration.MIGRATE_REPO_PATH, None, sanity_check=True) def test_legacy_db_version_control(self): migration.db_version_control = mock.Mock() self._main_test_helper(['glance.cmd.manage', 'db_version_control'], migration.db_version_control, db_api.get_engine(), db_migration.MIGRATE_REPO_PATH, None) def test_legacy_db_sync_version(self): migration.db_sync = mock.Mock() self._main_test_helper(['glance.cmd.manage', 'db_sync', '20'], migration.db_sync, db_api.get_engine(), db_migration.MIGRATE_REPO_PATH, '20', sanity_check=True) def test_legacy_db_upgrade_version(self): migration.db_sync = mock.Mock() self._main_test_helper(['glance.cmd.manage', 'db_upgrade', '20'], migration.db_sync, db_api.get_engine(), db_migration.MIGRATE_REPO_PATH, '20', sanity_check=True) def test_legacy_db_downgrade_version(self): migration.db_sync = mock.Mock() self._main_test_helper(['glance.cmd.manage', 'db_downgrade', '20'], migration.db_sync, db_api.get_engine(), db_migration.MIGRATE_REPO_PATH, '20', sanity_check=True) def test_legacy_db_sync_version_without_sanity_check(self): migration.db_sync = mock.Mock() manage.CONF.db_enforce_mysql_charset = False self._main_test_helper(['glance.cmd.manage', 'db_sync', '20'], migration.db_sync, db_api.get_engine(), db_migration.MIGRATE_REPO_PATH, '20', sanity_check=False) def test_legacy_db_upgrade_version_without_sanity_check(self): migration.db_sync = mock.Mock() manage.CONF.db_enforce_mysql_charset = False self._main_test_helper(['glance.cmd.manage', 'db_upgrade', '40'], migration.db_sync, db_api.get_engine(), db_migration.MIGRATE_REPO_PATH, '40', sanity_check=False) def test_legacy_db_downgrade_version_without_sanity_check(self): migration.db_sync = mock.Mock() manage.CONF.db_enforce_mysql_charset = False self._main_test_helper(['glance.cmd.manage', 'db_downgrade', '20'], migration.db_sync, db_api.get_engine(), db_migration.MIGRATE_REPO_PATH, '20', sanity_check=False) class TestManage(TestManageBase): def test_db_version(self): migration.db_version = mock.Mock() self._main_test_helper(['glance.cmd.manage', 'db', 'version'], migration.db_version, db_api.get_engine(), db_migration.MIGRATE_REPO_PATH, 0) def test_db_sync(self): migration.db_sync = mock.Mock() self._main_test_helper(['glance.cmd.manage', 'db', 'sync'], migration.db_sync, db_api.get_engine(), db_migration.MIGRATE_REPO_PATH, None, sanity_check=True) def test_db_upgrade(self): migration.db_sync = mock.Mock() self._main_test_helper(['glance.cmd.manage', 'db', 'upgrade'], migration.db_sync, db_api.get_engine(), db_migration.MIGRATE_REPO_PATH, None, sanity_check=True) def test_db_version_control(self): migration.db_version_control = mock.Mock() self._main_test_helper(['glance.cmd.manage', 'db', 'version_control'], migration.db_version_control, db_api.get_engine(), db_migration.MIGRATE_REPO_PATH, None) def test_db_sync_version(self): migration.db_sync = mock.Mock() self._main_test_helper(['glance.cmd.manage', 'db', 'sync', '20'], migration.db_sync, db_api.get_engine(), db_migration.MIGRATE_REPO_PATH, '20', sanity_check=True) def test_db_upgrade_version(self): migration.db_sync = mock.Mock() self._main_test_helper(['glance.cmd.manage', 'db', 'upgrade', '20'], migration.db_sync, db_api.get_engine(), db_migration.MIGRATE_REPO_PATH, '20', sanity_check=True) def test_db_downgrade_version(self): migration.db_sync = mock.Mock() self._main_test_helper(['glance.cmd.manage', 'db', 'downgrade', '20'], migration.db_sync, db_api.get_engine(), db_migration.MIGRATE_REPO_PATH, '20', sanity_check=True) def test_db_sync_version_without_sanity_check(self): migration.db_sync = mock.Mock() manage.CONF.db_enforce_mysql_charset = False self._main_test_helper(['glance.cmd.manage', 'db', 'sync', '20'], migration.db_sync, db_api.get_engine(), db_migration.MIGRATE_REPO_PATH, u'20', sanity_check=False) def test_db_upgrade_version_without_sanity_check(self): migration.db_sync = mock.Mock() manage.CONF.db_enforce_mysql_charset = False self._main_test_helper(['glance.cmd.manage', 'db', 'upgrade', '40'], migration.db_sync, db_api.get_engine(), db_migration.MIGRATE_REPO_PATH, '40', sanity_check=False) def test_db_downgrade_version_without_sanity_check(self): migration.db_sync = mock.Mock() manage.CONF.db_enforce_mysql_charset = False self._main_test_helper(['glance.cmd.manage', 'db', 'downgrade', '20'], migration.db_sync, db_api.get_engine(), db_migration.MIGRATE_REPO_PATH, '20', sanity_check=False) glance-2014.1/glance/tests/unit/test_quota.py0000664000175400017540000005156712323736230022323 0ustar jenkinsjenkins00000000000000# Copyright 2013, 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. import mock from mock import patch import uuid from glance.common import exception import glance.quota import glance.store from glance.tests.unit import utils as unit_test_utils from glance.tests import utils as test_utils UUID1 = 'c80a1a6c-bd1f-41c5-90ee-81afedb1d58d' class FakeContext(object): owner = 'someone' is_admin = False class FakeImage(object): size = None image_id = 'someid' locations = [{'url': 'file:///not/a/path', 'metadata': {}}] tags = set([]) def set_data(self, data, size=None): self.size = 0 for d in data: self.size += len(d) class TestImageQuota(test_utils.BaseTestCase): def setUp(self): super(TestImageQuota, self).setUp() def tearDown(self): super(TestImageQuota, self).tearDown() def _get_image(self, location_count=1, image_size=10): context = FakeContext() db_api = unit_test_utils.FakeDB() base_image = FakeImage() base_image.image_id = 'xyz' base_image.size = image_size image = glance.quota.ImageProxy(base_image, context, db_api) locations = [] for i in range(location_count): locations.append({'url': 'file:///g/there/it/is%d' % i, 'metadata': {}}) image_values = {'id': 'xyz', 'owner': context.owner, 'status': 'active', 'size': image_size, 'locations': locations} db_api.image_create(context, image_values) return image def test_quota_allowed(self): quota = 10 self.config(user_storage_quota=quota) context = FakeContext() db_api = unit_test_utils.FakeDB() base_image = FakeImage() base_image.image_id = 'id' image = glance.quota.ImageProxy(base_image, context, db_api) data = '*' * quota base_image.set_data(data, size=None) image.set_data(data) self.assertEqual(quota, base_image.size) def _quota_exceeded_size(self, quota, data, deleted=True, size=None): self.config(user_storage_quota=quota) context = FakeContext() db_api = unit_test_utils.FakeDB() base_image = FakeImage() base_image.image_id = 'id' image = glance.quota.ImageProxy(base_image, context, db_api) if deleted: with patch.object(glance.store, 'safe_delete_from_backend'): glance.store.safe_delete_from_backend( context, base_image.locations[0]['url'], image.image_id) self.assertRaises(exception.StorageQuotaFull, image.set_data, data, size=size) def test_quota_exceeded_no_size(self): quota = 10 data = '*' * (quota + 1) #NOTE(jbresnah) When the image size is None it means that it is # not known. In this case the only time we will raise an # exception is when there is no room left at all, thus we know # it will not fit. # That's why 'get_remaining_quota' is mocked with return_value = 0. with patch.object(glance.api.common, 'get_remaining_quota', return_value=0): self._quota_exceeded_size(quota, data) def test_quota_exceeded_with_right_size(self): quota = 10 data = '*' * (quota + 1) self._quota_exceeded_size(quota, data, size=len(data), deleted=False) def test_quota_exceeded_with_lie_size(self): quota = 10 data = '*' * (quota + 1) self._quota_exceeded_size(quota, data, deleted=False, size=quota - 1) def test_append_location(self): new_location = {'url': 'file:///a/path', 'metadata': {}} image = self._get_image() pre_add_locations = image.locations[:] image.locations.append(new_location) pre_add_locations.append(new_location) self.assertEqual(image.locations, pre_add_locations) def test_insert_location(self): new_location = {'url': 'file:///a/path', 'metadata': {}} image = self._get_image() pre_add_locations = image.locations[:] image.locations.insert(0, new_location) pre_add_locations.insert(0, new_location) self.assertEqual(image.locations, pre_add_locations) def test_extend_location(self): new_location = {'url': 'file:///a/path', 'metadata': {}} image = self._get_image() pre_add_locations = image.locations[:] image.locations.extend([new_location]) pre_add_locations.extend([new_location]) self.assertEqual(image.locations, pre_add_locations) def test_iadd_location(self): new_location = {'url': 'file:///a/path', 'metadata': {}} image = self._get_image() pre_add_locations = image.locations[:] image.locations += [new_location] pre_add_locations += [new_location] self.assertEqual(image.locations, pre_add_locations) def test_set_location(self): new_location = {'url': 'file:///a/path', 'metadata': {}} image = self._get_image() image.locations = [new_location] self.assertEqual(image.locations, [new_location]) def _make_image_with_quota(self, image_size=10, location_count=2): quota = image_size * location_count self.config(user_storage_quota=quota) return self._get_image(image_size=image_size, location_count=location_count) def test_exceed_append_location(self): image = self._make_image_with_quota() self.assertRaises(exception.StorageQuotaFull, image.locations.append, {'url': 'file:///a/path', 'metadata': {}}) def test_exceed_insert_location(self): image = self._make_image_with_quota() self.assertRaises(exception.StorageQuotaFull, image.locations.insert, 0, {'url': 'file:///a/path', 'metadata': {}}) def test_exceed_extend_location(self): image = self._make_image_with_quota() self.assertRaises(exception.StorageQuotaFull, image.locations.extend, [{'url': 'file:///a/path', 'metadata': {}}]) def test_set_location_under(self): image = self._make_image_with_quota(location_count=1) image.locations = [{'url': 'file:///a/path', 'metadata': {}}] def test_set_location_exceed(self): image = self._make_image_with_quota(location_count=1) try: image.locations = [{'url': 'file:///a/path', 'metadata': {}}, {'url': 'file:///a/path2', 'metadata': {}}] self.fail('Should have raised the quota exception') except exception.StorageQuotaFull: pass def test_iadd_location_exceed(self): image = self._make_image_with_quota(location_count=1) try: image.locations += [{'url': 'file:///a/path', 'metadata': {}}] self.fail('Should have raised the quota exception') except exception.StorageQuotaFull: pass def test_append_location_for_queued_image(self): context = FakeContext() db_api = unit_test_utils.FakeDB() base_image = FakeImage() base_image.image_id = str(uuid.uuid4()) image = glance.quota.ImageProxy(base_image, context, db_api) self.assertIsNone(image.size) self.stubs.Set(glance.store, 'get_size_from_backend', unit_test_utils.fake_get_size_from_backend) image.locations.append({'url': 'file:///fake.img.tar.gz', 'metadata': {}}) self.assertIn({'url': 'file:///fake.img.tar.gz', 'metadata': {}}, image.locations) def test_insert_location_for_queued_image(self): context = FakeContext() db_api = unit_test_utils.FakeDB() base_image = FakeImage() base_image.image_id = str(uuid.uuid4()) image = glance.quota.ImageProxy(base_image, context, db_api) self.assertIsNone(image.size) self.stubs.Set(glance.store, 'get_size_from_backend', unit_test_utils.fake_get_size_from_backend) image.locations.insert(0, {'url': 'file:///fake.img.tar.gz', 'metadata': {}}) self.assertIn({'url': 'file:///fake.img.tar.gz', 'metadata': {}}, image.locations) def test_set_location_for_queued_image(self): context = FakeContext() db_api = unit_test_utils.FakeDB() base_image = FakeImage() base_image.image_id = str(uuid.uuid4()) image = glance.quota.ImageProxy(base_image, context, db_api) self.assertIsNone(image.size) self.stubs.Set(glance.store, 'get_size_from_backend', unit_test_utils.fake_get_size_from_backend) image.locations = [{'url': 'file:///fake.img.tar.gz', 'metadata': {}}] self.assertEqual([{'url': 'file:///fake.img.tar.gz', 'metadata': {}}], image.locations) def test_iadd_location_for_queued_image(self): context = FakeContext() db_api = unit_test_utils.FakeDB() base_image = FakeImage() base_image.image_id = str(uuid.uuid4()) image = glance.quota.ImageProxy(base_image, context, db_api) self.assertIsNone(image.size) self.stubs.Set(glance.store, 'get_size_from_backend', unit_test_utils.fake_get_size_from_backend) image.locations += [{'url': 'file:///fake.img.tar.gz', 'metadata': {}}] self.assertIn({'url': 'file:///fake.img.tar.gz', 'metadata': {}}, image.locations) class TestImagePropertyQuotas(test_utils.BaseTestCase): def setUp(self): super(TestImagePropertyQuotas, self).setUp() self.base_image = mock.Mock() self.image = glance.quota.ImageProxy(self.base_image, mock.Mock(), mock.Mock()) self.image_repo_mock = mock.Mock() self.image_repo_proxy = glance.quota.ImageRepoProxy( self.image_repo_mock, mock.Mock(), mock.Mock()) def test_save_image_with_image_property(self): self.config(image_property_quota=1) self.image.extra_properties = {'foo': 'bar'} self.image_repo_proxy.save(self.image) self.image_repo_mock.save.assert_called_once_with(self.base_image) def test_save_image_too_many_image_properties(self): self.config(image_property_quota=1) self.image.extra_properties = {'foo': 'bar', 'foo2': 'bar2'} exc = self.assertRaises(exception.ImagePropertyLimitExceeded, self.image_repo_proxy.save, self.image) self.assertTrue("Attempted: 2, Maximum: 1" in str(exc)) def test_save_image_unlimited_image_properties(self): self.config(image_property_quota=-1) self.image.extra_properties = {'foo': 'bar'} self.image_repo_proxy.save(self.image) self.image_repo_mock.save.assert_called_once_with(self.base_image) def test_add_image_with_image_property(self): self.config(image_property_quota=1) self.image.extra_properties = {'foo': 'bar'} self.image_repo_proxy.add(self.image) self.image_repo_mock.add.assert_called_once_with(self.base_image) def test_add_image_too_many_image_properties(self): self.config(image_property_quota=1) self.image.extra_properties = {'foo': 'bar', 'foo2': 'bar2'} exc = self.assertRaises(exception.ImagePropertyLimitExceeded, self.image_repo_proxy.add, self.image) self.assertTrue("Attempted: 2, Maximum: 1" in str(exc)) def test_add_image_unlimited_image_properties(self): self.config(image_property_quota=-1) self.image.extra_properties = {'foo': 'bar'} self.image_repo_proxy.add(self.image) self.image_repo_mock.add.assert_called_once_with(self.base_image) class TestImageTagQuotas(test_utils.BaseTestCase): def setUp(self): super(TestImageTagQuotas, self).setUp() self.base_image = mock.Mock() self.base_image.tags = set([]) self.image = glance.quota.ImageProxy(self.base_image, mock.Mock(), mock.Mock()) self.image_repo_mock = mock.Mock() self.image_repo_proxy = glance.quota.ImageRepoProxy( self.image_repo_mock, mock.Mock(), mock.Mock()) def test_replace_image_tag(self): self.config(image_tag_quota=1) self.image.tags = ['foo'] self.assertEqual(len(self.image.tags), 1) def test_replace_too_many_image_tags(self): self.config(image_tag_quota=0) exc = self.assertRaises(exception.ImageTagLimitExceeded, setattr, self.image, 'tags', ['foo', 'bar']) self.assertTrue('Attempted: 2, Maximum: 0' in str(exc)) self.assertEqual(len(self.image.tags), 0) def test_replace_unlimited_image_tags(self): self.config(image_tag_quota=-1) self.image.tags = ['foo'] self.assertEqual(len(self.image.tags), 1) def test_add_image_tag(self): self.config(image_tag_quota=1) self.image.tags.add('foo') self.assertEqual(len(self.image.tags), 1) def test_add_too_many_image_tags(self): self.config(image_tag_quota=1) self.image.tags.add('foo') exc = self.assertRaises(exception.ImageTagLimitExceeded, self.image.tags.add, 'bar') self.assertTrue('Attempted: 2, Maximum: 1' in str(exc)) def test_add_unlimited_image_tags(self): self.config(image_tag_quota=-1) self.image.tags.add('foo') self.assertEqual(len(self.image.tags), 1) def test_remove_image_tag_while_over_quota(self): self.config(image_tag_quota=1) self.image.tags.add('foo') self.assertEqual(len(self.image.tags), 1) self.config(image_tag_quota=0) self.image.tags.remove('foo') self.assertEqual(len(self.image.tags), 0) class TestQuotaImageTagsProxy(test_utils.BaseTestCase): def setUp(self): super(TestQuotaImageTagsProxy, self).setUp() def test_add(self): proxy = glance.quota.QuotaImageTagsProxy(set([])) proxy.add('foo') self.assertTrue('foo' in proxy) def test_add_too_many_tags(self): self.config(image_tag_quota=0) proxy = glance.quota.QuotaImageTagsProxy(set([])) exc = self.assertRaises(exception.ImageTagLimitExceeded, proxy.add, 'bar') self.assertTrue('Attempted: 1, Maximum: 0' in str(exc)) def test_equals(self): proxy = glance.quota.QuotaImageTagsProxy(set([])) self.assertEqual(set([]), proxy) def test_contains(self): proxy = glance.quota.QuotaImageTagsProxy(set(['foo'])) self.assertTrue('foo' in proxy) def test_len(self): proxy = glance.quota.QuotaImageTagsProxy(set(['foo', 'bar', 'baz', 'niz'])) self.assertEqual(len(proxy), 4) def test_iter(self): items = set(['foo', 'bar', 'baz', 'niz']) proxy = glance.quota.QuotaImageTagsProxy(items.copy()) self.assertEqual(len(items), 4) for item in proxy: items.remove(item) self.assertEqual(len(items), 0) class TestImageMemberQuotas(test_utils.BaseTestCase): def setUp(self): super(TestImageMemberQuotas, self).setUp() db_api = unit_test_utils.FakeDB() context = FakeContext() self.image = mock.Mock() self.base_image_member_factory = mock.Mock() self.image_member_factory = glance.quota.ImageMemberFactoryProxy( self.base_image_member_factory, context, db_api) def test_new_image_member(self): self.config(image_member_quota=1) self.image_member_factory.new_image_member(self.image, 'fake_id') self.base_image_member_factory.new_image_member\ .assert_called_once_with(self.image.base, 'fake_id') def test_new_image_member_unlimited_members(self): self.config(image_member_quota=-1) self.image_member_factory.new_image_member(self.image, 'fake_id') self.base_image_member_factory.new_image_member\ .assert_called_once_with(self.image.base, 'fake_id') def test_new_image_member_too_many_members(self): self.config(image_member_quota=0) self.assertRaises(exception.ImageMemberLimitExceeded, self.image_member_factory.new_image_member, self.image, 'fake_id') class TestImageLocationQuotas(test_utils.BaseTestCase): def setUp(self): super(TestImageLocationQuotas, self).setUp() self.base_image = mock.Mock() self.base_image.locations = [] self.base_image.size = 1 self.image = glance.quota.ImageProxy(self.base_image, mock.Mock(), mock.Mock()) self.image_repo_mock = mock.Mock() self.image_repo_proxy = glance.quota.ImageRepoProxy( self.image_repo_mock, mock.Mock(), mock.Mock()) def test_replace_image_location(self): self.config(image_location_quota=1) self.image.locations = [{"url": "file:///fake.img.tar.gz", "metadata": {} }] self.assertEqual(len(self.image.locations), 1) def test_replace_too_many_image_locations(self): self.config(image_location_quota=1) self.image.locations = [{"url": "file:///fake.img.tar.gz", "metadata": {}} ] locations = [ {"url": "file:///fake1.img.tar.gz", "metadata": {}}, {"url": "file:///fake2.img.tar.gz", "metadata": {}}, {"url": "file:///fake3.img.tar.gz", "metadata": {}} ] exc = self.assertRaises(exception.ImageLocationLimitExceeded, setattr, self.image, 'locations', locations) self.assertTrue('Attempted: 3, Maximum: 1' in str(exc)) self.assertEqual(len(self.image.locations), 1) def test_replace_unlimited_image_locations(self): self.config(image_location_quota=-1) self.image.locations = [{"url": "file:///fake.img.tar.gz", "metadata": {}} ] self.assertEqual(len(self.image.locations), 1) def test_add_image_location(self): self.config(image_location_quota=1) location = {"url": "file:///fake.img.tar.gz", "metadata": {}} self.image.locations.append(location) self.assertEqual(len(self.image.locations), 1) def test_add_too_many_image_locations(self): self.config(image_location_quota=1) location1 = {"url": "file:///fake1.img.tar.gz", "metadata": {}} self.image.locations.append(location1) location2 = {"url": "file:///fake2.img.tar.gz", "metadata": {}} exc = self.assertRaises(exception.ImageLocationLimitExceeded, self.image.locations.append, location2) self.assertTrue('Attempted: 2, Maximum: 1' in str(exc)) def test_add_unlimited_image_locations(self): self.config(image_location_quota=-1) location1 = {"url": "file:///fake1.img.tar.gz", "metadata": {}} self.image.locations.append(location1) self.assertEqual(len(self.image.locations), 1) def test_remove_image_location_while_over_quota(self): self.config(image_location_quota=1) location1 = {"url": "file:///fake1.img.tar.gz", "metadata": {}} self.image.locations.append(location1) self.assertEqual(len(self.image.locations), 1) self.config(image_location_quota=0) self.image.locations.remove(location1) self.assertEqual(len(self.image.locations), 0) glance-2014.1/glance/tests/unit/test_misc.py0000664000175400017540000000512612323736226022120 0ustar jenkinsjenkins00000000000000# Copyright 2010-2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import os from glance.common import crypt from glance.common import utils from glance.tests import utils as test_utils class UtilsTestCase(test_utils.BaseTestCase): def test_encryption(self): # Check that original plaintext and unencrypted ciphertext match # Check keys of the three allowed lengths key_list = ["1234567890abcdef", "12345678901234567890abcd", "1234567890abcdef1234567890ABCDEF"] plaintext_list = [''] blocksize = 64 for i in range(3 * blocksize): plaintext_list.append(os.urandom(i)) for key in key_list: for plaintext in plaintext_list: ciphertext = crypt.urlsafe_encrypt(key, plaintext, blocksize) self.assertTrue(ciphertext != plaintext) text = crypt.urlsafe_decrypt(key, ciphertext) self.assertTrue(plaintext == text) def test_empty_metadata_headers(self): """Ensure unset metadata is not encoded in HTTP headers""" metadata = { 'foo': 'bar', 'snafu': None, 'bells': 'whistles', 'unset': None, 'empty': '', 'properties': { 'distro': '', 'arch': None, 'user': 'nobody', }, } headers = utils.image_meta_to_http_headers(metadata) self.assertFalse('x-image-meta-snafu' in headers) self.assertFalse('x-image-meta-uset' in headers) self.assertFalse('x-image-meta-snafu' in headers) self.assertFalse('x-image-meta-property-arch' in headers) self.assertEqual(headers.get('x-image-meta-foo'), 'bar') self.assertEqual(headers.get('x-image-meta-bells'), 'whistles') self.assertEqual(headers.get('x-image-meta-empty'), '') self.assertEqual(headers.get('x-image-meta-property-distro'), '') self.assertEqual(headers.get('x-image-meta-property-user'), 'nobody') glance-2014.1/glance/tests/unit/test_vmware_store.py0000664000175400017540000002322612323736226023703 0ustar jenkinsjenkins00000000000000# Copyright 2014 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. """Tests the VMware Datastore backend store""" import hashlib import uuid import mock import six from glance.common import exception from glance.openstack.common import units from glance.store.location import get_location_from_uri import glance.store.vmware_datastore as vm_store from glance.store.vmware_datastore import Store from glance.tests.unit import base from glance.tests import utils FAKE_UUID = str(uuid.uuid4()) FIVE_KB = 5 * units.Ki VMWARE_DATASTORE_CONF = { 'verbose': True, 'debug': True, 'known_stores': ['glance.store.vmware_datastore.Store'], 'default_store': 'vsphere', 'vmware_server_host': '127.0.0.1', 'vmware_server_username': 'username', 'vmware_server_password': 'password', 'vmware_datacenter_path': 'dc1', 'vmware_datastore_name': 'ds1', 'vmware_store_image_dir': '/openstack_glance', 'vmware_api_insecure': 'True' } def format_location(host_ip, folder_name, image_id, datacenter_path, datastore_name): """ Helper method that returns a VMware Datastore store URI given the component pieces. """ scheme = 'vsphere' return ("%s://%s/folder%s/%s?dsName=%s&dcPath=%s" % (scheme, host_ip, folder_name, image_id, datastore_name, datacenter_path)) class FakeHTTPConnection(object): def __init__(self, status=200, *args, **kwargs): self.status = status pass def getresponse(self): return utils.FakeHTTPResponse(status=self.status) def request(self, *_args, **_kwargs): pass def close(self): pass class TestStore(base.StoreClearingUnitTest): @mock.patch('oslo.vmware.api.VMwareAPISession', autospec=True) def setUp(self, mock_session): """Establish a clean test environment""" self.config(default_store='file') # NOTE(flaper87): Each store should test # this in their test suite. self.config(known_stores=VMWARE_DATASTORE_CONF['known_stores']) super(TestStore, self).setUp() Store.CHUNKSIZE = 2 self.store = Store() class FakeSession: def __init__(self): self.vim = FakeVim() class FakeVim: def __init__(self): self.client = FakeClient() class FakeClient: def __init__(self): self.options = FakeOptions() class FakeOptions: def __init__(self): self.transport = FakeTransport() class FakeTransport: def __init__(self): self.cookiejar = FakeCookieJar() class FakeCookieJar: pass self.store.scheme = VMWARE_DATASTORE_CONF['default_store'] self.store.server_host = ( VMWARE_DATASTORE_CONF['vmware_server_host']) self.store.datacenter_path = ( VMWARE_DATASTORE_CONF['vmware_datacenter_path']) self.store.datastore_name = ( VMWARE_DATASTORE_CONF['vmware_datastore_name']) self.store.api_insecure = ( VMWARE_DATASTORE_CONF['vmware_api_insecure']) self.store._session = FakeSession() self.store._session.invoke_api = mock.Mock() self.store._session.wait_for_task = mock.Mock() self.store.store_image_dir = ( VMWARE_DATASTORE_CONF['vmware_store_image_dir']) Store._build_vim_cookie_header = mock.Mock() self.addCleanup(self.stubs.UnsetAll) def test_get(self): """Test a "normal" retrieval of an image in chunks""" expected_image_size = 31 expected_returns = ['I ', 'am', ' a', ' t', 'ea', 'po', 't,', ' s', 'ho', 'rt', ' a', 'nd', ' s', 'to', 'ut', '\n'] loc = get_location_from_uri( "vsphere://127.0.0.1/folder/openstack_glance/%s" "?dsName=ds1&dcPath=dc1" % FAKE_UUID) with mock.patch('httplib.HTTPConnection') as HttpConn: HttpConn.return_value = FakeHTTPConnection() (image_file, image_size) = self.store.get(loc) self.assertEqual(image_size, expected_image_size) chunks = [c for c in image_file] self.assertEqual(chunks, expected_returns) def test_get_non_existing(self): """ Test that trying to retrieve an image that doesn't exist raises an error """ loc = get_location_from_uri("vsphere://127.0.0.1/folder/openstack_glan" "ce/%s?dsName=ds1&dcPath=dc1" % FAKE_UUID) with mock.patch('httplib.HTTPConnection') as HttpConn: HttpConn.return_value = FakeHTTPConnection(status=404) self.assertRaises(exception.NotFound, self.store.get, loc) @mock.patch.object(vm_store._Reader, 'size') def test_add(self, fake_size): """Test that we can add an image via the VMware backend""" expected_image_id = str(uuid.uuid4()) expected_size = FIVE_KB expected_contents = "*" * expected_size hash_code = hashlib.md5(expected_contents) expected_checksum = hash_code.hexdigest() fake_size.__get__ = mock.Mock(return_value=expected_size) with mock.patch('hashlib.md5') as md5: md5.return_value = hash_code expected_location = format_location( VMWARE_DATASTORE_CONF['vmware_server_host'], VMWARE_DATASTORE_CONF['vmware_store_image_dir'], expected_image_id, VMWARE_DATASTORE_CONF['vmware_datacenter_path'], VMWARE_DATASTORE_CONF['vmware_datastore_name']) image = six.StringIO(expected_contents) with mock.patch('httplib.HTTPConnection') as HttpConn: HttpConn.return_value = FakeHTTPConnection() location, size, checksum, _ = self.store.add(expected_image_id, image, expected_size) self.assertEqual(expected_location, location) self.assertEqual(expected_size, size) self.assertEqual(expected_checksum, checksum) @mock.patch.object(vm_store._Reader, 'size') def test_add_size_zero(self, fake_size): """ Test that when specifying size zero for the image to add, the actual size of the image is returned. """ expected_image_id = str(uuid.uuid4()) expected_size = FIVE_KB expected_contents = "*" * expected_size hash_code = hashlib.md5(expected_contents) expected_checksum = hash_code.hexdigest() fake_size.__get__ = mock.Mock(return_value=expected_size) with mock.patch('hashlib.md5') as md5: md5.return_value = hash_code expected_location = format_location( VMWARE_DATASTORE_CONF['vmware_server_host'], VMWARE_DATASTORE_CONF['vmware_store_image_dir'], expected_image_id, VMWARE_DATASTORE_CONF['vmware_datacenter_path'], VMWARE_DATASTORE_CONF['vmware_datastore_name']) image = six.StringIO(expected_contents) with mock.patch('httplib.HTTPConnection') as HttpConn: HttpConn.return_value = FakeHTTPConnection() location, size, checksum, _ = self.store.add(expected_image_id, image, 0) self.assertEqual(expected_location, location) self.assertEqual(expected_size, size) self.assertEqual(expected_checksum, checksum) def test_delete(self): """Test we can delete an existing image in the VMware store""" loc = get_location_from_uri( "vsphere://127.0.0.1/folder/openstack_glance/%s?" "dsName=ds1&dcPath=dc1" % FAKE_UUID) with mock.patch('httplib.HTTPConnection') as HttpConn: HttpConn.return_value = FakeHTTPConnection() Store._service_content = mock.Mock() self.store.delete(loc) with mock.patch('httplib.HTTPConnection') as HttpConn: HttpConn.return_value = FakeHTTPConnection(status=404) self.assertRaises(exception.NotFound, self.store.get, loc) def test_get_size(self): """Test we can get the size of an existing image in the VMware store""" loc = get_location_from_uri( "vsphere://127.0.0.1/folder/openstack_glance/%s" "?dsName=ds1&dcPath=dc1" % FAKE_UUID) with mock.patch('httplib.HTTPConnection') as HttpConn: HttpConn.return_value = FakeHTTPConnection() image_size = self.store.get_size(loc) self.assertEqual(image_size, 31) def test_get_size_non_existing(self): """ Test that trying to retrieve an image size that doesn't exist raises an error """ loc = get_location_from_uri("vsphere://127.0.0.1/folder/openstack_glan" "ce/%s?dsName=ds1&dcPath=dc1" % FAKE_UUID) with mock.patch('httplib.HTTPConnection') as HttpConn: HttpConn.return_value = FakeHTTPConnection(status=404) self.assertRaises(exception.NotFound, self.store.get_size, loc) glance-2014.1/glance/tests/unit/test_db.py0000664000175400017540000006623312323736230021553 0ustar jenkinsjenkins00000000000000# Copyright 2012 OpenStack Foundation. # Copyright 2013 IBM Corp. # 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 uuid import mock from oslo.config import cfg from glance.common import crypt from glance.common import exception import glance.context import glance.db import glance.tests.unit.utils as unit_test_utils import glance.tests.utils as test_utils CONF = cfg.CONF CONF.import_opt('metadata_encryption_key', 'glance.common.config') @mock.patch('glance.openstack.common.importutils.import_module') class TestDbUtilities(test_utils.BaseTestCase): def setUp(self): super(TestDbUtilities, self).setUp() self.config(data_api='silly pants') self.api = mock.Mock() def test_get_api_calls_configure_if_present(self, import_module): import_module.return_value = self.api self.assertEqual(glance.db.get_api(), self.api) import_module.assert_called_once_with('silly pants') self.api.configure.assert_called_once_with() def test_get_api_skips_configure_if_missing(self, import_module): import_module.return_value = self.api del self.api.configure self.assertEqual(glance.db.get_api(), self.api) import_module.assert_called_once_with('silly pants') self.assertFalse(hasattr(self.api, 'configure')) UUID1 = 'c80a1a6c-bd1f-41c5-90ee-81afedb1d58d' UUID2 = 'a85abd86-55b3-4d5b-b0b4-5d0a6e6042fc' UUID3 = '971ec09a-8067-4bc8-a91f-ae3557f1c4c7' UUID4 = '6bbe7cc2-eae7-4c0f-b50d-a7160b0c6a86' TENANT1 = '6838eb7b-6ded-434a-882c-b344c77fe8df' TENANT2 = '2c014f32-55eb-467d-8fcb-4bd706012f81' TENANT3 = '5a3e60e8-cfa9-4a9e-a90a-62b42cea92b8' TENANT4 = 'c6c87f25-8a94-47ed-8c83-053c25f42df4' USER1 = '54492ba0-f4df-4e4e-be62-27f4d76b29cf' UUID1_LOCATION = 'file:///path/to/image' UUID1_LOCATION_METADATA = {'key': 'value'} UUID3_LOCATION = 'http://somehost.com/place' CHECKSUM = '93264c3edf5972c9f1cb309543d38a5c' CHCKSUM1 = '43264c3edf4972c9f1cb309543d38a55' def _db_fixture(id, **kwargs): obj = { 'id': id, 'name': None, 'is_public': False, 'properties': {}, 'checksum': None, 'owner': None, 'status': 'queued', 'tags': [], 'size': None, 'locations': [], 'protected': False, 'disk_format': None, 'container_format': None, 'deleted': False, 'min_ram': None, 'min_disk': None, } obj.update(kwargs) return obj def _db_image_member_fixture(image_id, member_id, **kwargs): obj = { 'image_id': image_id, 'member': member_id, } obj.update(kwargs) return obj def _db_task_fixture(task_id, type, status, **kwargs): obj = { 'id': task_id, 'type': type, 'status': status, 'input': None, 'result': None, 'owner': None, 'message': None, 'deleted': False, } obj.update(kwargs) return obj class TestImageRepo(test_utils.BaseTestCase): def setUp(self): super(TestImageRepo, self).setUp() self.db = unit_test_utils.FakeDB() self.db.reset() self.context = glance.context.RequestContext( user=USER1, tenant=TENANT1) self.image_repo = glance.db.ImageRepo(self.context, self.db) self.image_factory = glance.domain.ImageFactory() self._create_images() self._create_image_members() def _create_images(self): self.db.reset() self.images = [ _db_fixture(UUID1, owner=TENANT1, checksum=CHECKSUM, name='1', size=256, is_public=True, status='active', locations=[{'url': UUID1_LOCATION, 'metadata': UUID1_LOCATION_METADATA}]), _db_fixture(UUID2, owner=TENANT1, checksum=CHCKSUM1, name='2', size=512, is_public=False), _db_fixture(UUID3, owner=TENANT3, checksum=CHCKSUM1, name='3', size=1024, is_public=True, locations=[{'url': UUID3_LOCATION, 'metadata': {}}]), _db_fixture(UUID4, owner=TENANT4, name='4', size=2048), ] [self.db.image_create(None, image) for image in self.images] self.db.image_tag_set_all(None, UUID1, ['ping', 'pong']) def _create_image_members(self): self.image_members = [ _db_image_member_fixture(UUID2, TENANT2), _db_image_member_fixture(UUID2, TENANT3, status='accepted'), ] [self.db.image_member_create(None, image_member) for image_member in self.image_members] def test_get(self): image = self.image_repo.get(UUID1) self.assertEqual(image.image_id, UUID1) self.assertEqual(image.name, '1') self.assertEqual(image.tags, set(['ping', 'pong'])) self.assertEqual(image.visibility, 'public') self.assertEqual(image.status, 'active') self.assertEqual(image.size, 256) self.assertEqual(image.owner, TENANT1) def test_location_value(self): image = self.image_repo.get(UUID3) self.assertEqual(image.locations[0]['url'], UUID3_LOCATION) def test_location_data_value(self): image = self.image_repo.get(UUID1) self.assertEqual(image.locations[0]['url'], UUID1_LOCATION) self.assertEqual(image.locations[0]['metadata'], UUID1_LOCATION_METADATA) def test_location_data_exists(self): image = self.image_repo.get(UUID2) self.assertEqual(image.locations, []) def test_get_not_found(self): fake_uuid = str(uuid.uuid4()) exc = self.assertRaises(exception.NotFound, self.image_repo.get, fake_uuid) self.assertTrue(fake_uuid in unicode(exc)) def test_get_forbidden(self): self.assertRaises(exception.NotFound, self.image_repo.get, UUID4) def test_list(self): images = self.image_repo.list() image_ids = set([i.image_id for i in images]) self.assertEqual(set([UUID1, UUID2, UUID3]), image_ids) def _do_test_list_status(self, status, expected): self.context = glance.context.RequestContext( user=USER1, tenant=TENANT3) self.image_repo = glance.db.ImageRepo(self.context, self.db) images = self.image_repo.list(member_status=status) self.assertEqual(expected, len(images)) def test_list_status(self): self._do_test_list_status(None, 3) def test_list_status_pending(self): self._do_test_list_status('pending', 2) def test_list_status_rejected(self): self._do_test_list_status('rejected', 2) def test_list_status_all(self): self._do_test_list_status('all', 3) def test_list_with_marker(self): full_images = self.image_repo.list() full_ids = [i.image_id for i in full_images] marked_images = self.image_repo.list(marker=full_ids[0]) actual_ids = [i.image_id for i in marked_images] self.assertEqual(actual_ids, full_ids[1:]) def test_list_with_last_marker(self): images = self.image_repo.list() marked_images = self.image_repo.list(marker=images[-1].image_id) self.assertEqual(len(marked_images), 0) def test_limited_list(self): limited_images = self.image_repo.list(limit=2) self.assertEqual(len(limited_images), 2) def test_list_with_marker_and_limit(self): full_images = self.image_repo.list() full_ids = [i.image_id for i in full_images] marked_images = self.image_repo.list(marker=full_ids[0], limit=1) actual_ids = [i.image_id for i in marked_images] self.assertEqual(actual_ids, full_ids[1:2]) def test_list_private_images(self): filters = {'visibility': 'private'} images = self.image_repo.list(filters=filters) image_ids = set([i.image_id for i in images]) self.assertEqual(set([UUID2]), image_ids) def test_list_with_checksum_filter_single_image(self): filters = {'checksum': CHECKSUM} images = self.image_repo.list(filters=filters) image_ids = list([i.image_id for i in images]) self.assertEqual(1, len(image_ids)) self.assertEqual([UUID1], image_ids) def test_list_with_checksum_filter_multiple_images(self): filters = {'checksum': CHCKSUM1} images = self.image_repo.list(filters=filters) image_ids = list([i.image_id for i in images]) self.assertEqual(2, len(image_ids)) self.assertEqual([UUID3, UUID2], image_ids) def test_list_with_wrong_checksum(self): WRONG_CHKSUM = 'd2fd42f979e1ed1aafadc7eb9354bff839c858cd' filters = {'checksum': WRONG_CHKSUM} images = self.image_repo.list(filters=filters) self.assertEqual(0, len(images)) def test_list_with_tags_filter_single_tag(self): filters = {'tags': ['ping']} images = self.image_repo.list(filters=filters) image_ids = list([i.image_id for i in images]) self.assertEqual(1, len(image_ids)) self.assertEqual([UUID1], image_ids) def test_list_with_tags_filter_multiple_tags(self): filters = {'tags': ['ping', 'pong']} images = self.image_repo.list(filters=filters) image_ids = list([i.image_id for i in images]) self.assertEqual(1, len(image_ids)) self.assertEqual([UUID1], image_ids) def test_list_with_tags_filter_multiple_tags_and_nonexistent(self): filters = {'tags': ['ping', 'fake']} images = self.image_repo.list(filters=filters) image_ids = list([i.image_id for i in images]) self.assertEqual(0, len(image_ids)) def test_list_with_wrong_tags(self): filters = {'tags': ['fake']} images = self.image_repo.list(filters=filters) self.assertEqual(0, len(images)) def test_list_public_images(self): filters = {'visibility': 'public'} images = self.image_repo.list(filters=filters) image_ids = set([i.image_id for i in images]) self.assertEqual(set([UUID1, UUID3]), image_ids) def test_sorted_list(self): images = self.image_repo.list(sort_key='size', sort_dir='asc') image_ids = [i.image_id for i in images] self.assertEqual([UUID1, UUID2, UUID3], image_ids) def test_add_image(self): image = self.image_factory.new_image(name='added image') self.assertEqual(image.updated_at, image.created_at) self.image_repo.add(image) retreived_image = self.image_repo.get(image.image_id) self.assertEqual(retreived_image.name, 'added image') self.assertEqual(retreived_image.updated_at, image.updated_at) def test_save_image(self): image = self.image_repo.get(UUID1) original_update_time = image.updated_at image.name = 'foo' image.tags = ['king', 'kong'] self.image_repo.save(image) current_update_time = image.updated_at self.assertTrue(current_update_time > original_update_time) image = self.image_repo.get(UUID1) self.assertEqual(image.name, 'foo') self.assertEqual(image.tags, set(['king', 'kong'])) self.assertEqual(image.updated_at, current_update_time) def test_save_image_not_found(self): fake_uuid = str(uuid.uuid4()) image = self.image_repo.get(UUID1) image.image_id = fake_uuid exc = self.assertRaises(exception.NotFound, self.image_repo.save, image) self.assertTrue(fake_uuid in unicode(exc)) def test_remove_image(self): image = self.image_repo.get(UUID1) previous_update_time = image.updated_at self.image_repo.remove(image) self.assertTrue(image.updated_at > previous_update_time) self.assertRaises(exception.NotFound, self.image_repo.get, UUID1) def test_remove_image_not_found(self): fake_uuid = str(uuid.uuid4()) image = self.image_repo.get(UUID1) image.image_id = fake_uuid exc = self.assertRaises(exception.NotFound, self.image_repo.remove, image) self.assertTrue(fake_uuid in unicode(exc)) class TestEncryptedLocations(test_utils.BaseTestCase): def setUp(self): super(TestEncryptedLocations, self).setUp() self.db = unit_test_utils.FakeDB() self.db.reset() self.context = glance.context.RequestContext( user=USER1, tenant=TENANT1) self.image_repo = glance.db.ImageRepo(self.context, self.db) self.image_factory = glance.domain.ImageFactory() self.crypt_key = '0123456789abcdef' self.config(metadata_encryption_key=self.crypt_key) self.foo_bar_location = [{'url': 'foo', 'metadata': {}}, {'url': 'bar', 'metadata': {}}] def test_encrypt_locations_on_add(self): image = self.image_factory.new_image(UUID1) image.locations = self.foo_bar_location self.image_repo.add(image) db_data = self.db.image_get(self.context, UUID1) self.assertNotEqual(db_data['locations'], ['foo', 'bar']) decrypted_locations = [crypt.urlsafe_decrypt(self.crypt_key, l['url']) for l in db_data['locations']] self.assertEqual(decrypted_locations, [l['url'] for l in self.foo_bar_location]) def test_encrypt_locations_on_save(self): image = self.image_factory.new_image(UUID1) self.image_repo.add(image) image.locations = self.foo_bar_location self.image_repo.save(image) db_data = self.db.image_get(self.context, UUID1) self.assertNotEqual(db_data['locations'], ['foo', 'bar']) decrypted_locations = [crypt.urlsafe_decrypt(self.crypt_key, l['url']) for l in db_data['locations']] self.assertEqual(decrypted_locations, [l['url'] for l in self.foo_bar_location]) def test_decrypt_locations_on_get(self): url_loc = ['ping', 'pong'] orig_locations = [{'url': l, 'metadata': {}} for l in url_loc] encrypted_locs = [crypt.urlsafe_encrypt(self.crypt_key, l) for l in url_loc] encrypted_locations = [{'url': l, 'metadata': {}} for l in encrypted_locs] self.assertNotEqual(encrypted_locations, orig_locations) db_data = _db_fixture(UUID1, owner=TENANT1, locations=encrypted_locations) self.db.image_create(None, db_data) image = self.image_repo.get(UUID1) self.assertEqual(image.locations, orig_locations) def test_decrypt_locations_on_list(self): url_loc = ['ping', 'pong'] orig_locations = [{'url': l, 'metadata': {}} for l in url_loc] encrypted_locs = [crypt.urlsafe_encrypt(self.crypt_key, l) for l in url_loc] encrypted_locations = [{'url': l, 'metadata': {}} for l in encrypted_locs] self.assertNotEqual(encrypted_locations, orig_locations) db_data = _db_fixture(UUID1, owner=TENANT1, locations=encrypted_locations) self.db.image_create(None, db_data) image = self.image_repo.list()[0] self.assertEqual(image.locations, orig_locations) class TestImageMemberRepo(test_utils.BaseTestCase): def setUp(self): super(TestImageMemberRepo, self).setUp() self.db = unit_test_utils.FakeDB() self.db.reset() self.context = glance.context.RequestContext( user=USER1, tenant=TENANT1) self.image_repo = glance.db.ImageRepo(self.context, self.db) self.image_member_factory = glance.domain.ImageMemberFactory() self._create_images() self._create_image_members() image = self.image_repo.get(UUID1) self.image_member_repo = glance.db.ImageMemberRepo(self.context, self.db, image) def _create_images(self): self.images = [ _db_fixture(UUID1, owner=TENANT1, name='1', size=256, status='active'), _db_fixture(UUID2, owner=TENANT1, name='2', size=512, is_public=False), ] [self.db.image_create(None, image) for image in self.images] self.db.image_tag_set_all(None, UUID1, ['ping', 'pong']) def _create_image_members(self): self.image_members = [ _db_image_member_fixture(UUID1, TENANT2), _db_image_member_fixture(UUID1, TENANT3), ] [self.db.image_member_create(None, image_member) for image_member in self.image_members] def test_list(self): image_members = self.image_member_repo.list() image_member_ids = set([i.member_id for i in image_members]) self.assertEqual(set([TENANT2, TENANT3]), image_member_ids) def test_list_no_members(self): image = self.image_repo.get(UUID2) self.image_member_repo_uuid2 = glance.db.ImageMemberRepo( self.context, self.db, image) image_members = self.image_member_repo_uuid2.list() image_member_ids = set([i.member_id for i in image_members]) self.assertEqual(set([]), image_member_ids) def test_save_image_member(self): image_member = self.image_member_repo.get(TENANT2) image_member.status = 'accepted' self.image_member_repo.save(image_member) image_member_updated = self.image_member_repo.get(TENANT2) self.assertEqual(image_member.id, image_member_updated.id) self.assertEqual(image_member_updated.status, 'accepted') def test_add_image_member(self): image = self.image_repo.get(UUID1) image_member = self.image_member_factory.new_image_member(image, TENANT4) self.assertTrue(image_member.id is None) self.image_member_repo.add(image_member) retreived_image_member = self.image_member_repo.get(TENANT4) self.assertIsNotNone(retreived_image_member.id) self.assertEqual(retreived_image_member.image_id, image_member.image_id) self.assertEqual(retreived_image_member.member_id, image_member.member_id) self.assertEqual(retreived_image_member.status, 'pending') def test_add_duplicate_image_member(self): image = self.image_repo.get(UUID1) image_member = self.image_member_factory.new_image_member(image, TENANT4) self.assertTrue(image_member.id is None) self.image_member_repo.add(image_member) retreived_image_member = self.image_member_repo.get(TENANT4) self.assertIsNotNone(retreived_image_member.id) self.assertEqual(retreived_image_member.image_id, image_member.image_id) self.assertEqual(retreived_image_member.member_id, image_member.member_id) self.assertEqual(retreived_image_member.status, 'pending') self.assertRaises(exception.Duplicate, self.image_member_repo.add, image_member) def test_get_image_member(self): image = self.image_repo.get(UUID1) image_member = self.image_member_factory.new_image_member(image, TENANT4) self.assertIsNone(image_member.id) self.image_member_repo.add(image_member) member = self.image_member_repo.get(image_member.member_id) self.assertEqual(member.id, image_member.id) self.assertEqual(member.image_id, image_member.image_id) self.assertEqual(member.member_id, image_member.member_id) self.assertEqual(member.status, 'pending') def test_get_nonexistent_image_member(self): fake_image_member_id = 'fake' self.assertRaises(exception.NotFound, self.image_member_repo.get, fake_image_member_id) def test_remove_image_member(self): image_member = self.image_member_repo.get(TENANT2) self.image_member_repo.remove(image_member) self.assertRaises(exception.NotFound, self.image_member_repo.get, TENANT2) def test_remove_image_member_does_not_exist(self): fake_uuid = str(uuid.uuid4()) image = self.image_repo.get(UUID2) fake_member = glance.domain.ImageMemberFactory()\ .new_image_member(image, TENANT4) fake_member.id = fake_uuid exc = self.assertRaises(exception.NotFound, self.image_member_repo.remove, fake_member) self.assertTrue(fake_uuid in unicode(exc)) class TestTaskRepo(test_utils.BaseTestCase): def setUp(self): super(TestTaskRepo, self).setUp() self.db = unit_test_utils.FakeDB() self.db.reset() self.context = glance.context.RequestContext(user=USER1, tenant=TENANT1) self.task_repo = glance.db.TaskRepo(self.context, self.db) self.task_factory = glance.domain.TaskFactory() self.fake_task_input = ('{"import_from": ' '"swift://cloud.foo/account/mycontainer/path"' ',"image_from_format": "qcow2"}') self._create_tasks() def _create_tasks(self): self.db.reset() self.tasks = [ _db_task_fixture(UUID1, type='import', status='pending', input=self.fake_task_input, result='', owner=TENANT1, message='', ), _db_task_fixture(UUID2, type='import', status='processing', input=self.fake_task_input, result='', owner=TENANT1, message='', ), _db_task_fixture(UUID3, type='import', status='failure', input=self.fake_task_input, result='', owner=TENANT1, message='', ), _db_task_fixture(UUID4, type='import', status='success', input=self.fake_task_input, result='', owner=TENANT2, message='', ), ] [self.db.task_create(None, task) for task in self.tasks] def test_get(self): task, task_details = self.task_repo.get_task_and_details(UUID1) self.assertEqual(task.task_id, UUID1) self.assertEqual(task.type, 'import') self.assertEqual(task.status, 'pending') self.assertEqual(task.task_id, task_details.task_id) self.assertEqual(task_details.input, self.fake_task_input) self.assertEqual(task_details.result, '') self.assertEqual(task.owner, TENANT1) def test_get_not_found(self): self.assertRaises(exception.NotFound, self.task_repo.get_task_and_details, str(uuid.uuid4())) def test_get_forbidden(self): self.assertRaises(exception.NotFound, self.task_repo.get_task_and_details, UUID4) def test_list(self): tasks = self.task_repo.list_tasks() task_ids = set([i.task_id for i in tasks]) self.assertEqual(set([UUID1, UUID2, UUID3]), task_ids) def test_list_with_type(self): filters = {'type': 'import'} tasks = self.task_repo.list_tasks(filters=filters) task_ids = set([i.task_id for i in tasks]) self.assertEqual(set([UUID1, UUID2, UUID3]), task_ids) def test_list_with_status(self): filters = {'status': 'failure'} tasks = self.task_repo.list_tasks(filters=filters) task_ids = set([i.task_id for i in tasks]) self.assertEqual(set([UUID3]), task_ids) def test_list_with_marker(self): full_tasks = self.task_repo.list_tasks() full_ids = [i.task_id for i in full_tasks] marked_tasks = self.task_repo.list_tasks(marker=full_ids[0]) actual_ids = [i.task_id for i in marked_tasks] self.assertEqual(actual_ids, full_ids[1:]) def test_list_with_last_marker(self): tasks = self.task_repo.list_tasks() marked_tasks = self.task_repo.list_tasks(marker=tasks[-1].task_id) self.assertEqual(len(marked_tasks), 0) def test_limited_list(self): limited_tasks = self.task_repo.list_tasks(limit=2) self.assertEqual(len(limited_tasks), 2) def test_list_with_marker_and_limit(self): full_tasks = self.task_repo.list_tasks() full_ids = [i.task_id for i in full_tasks] marked_tasks = self.task_repo.list_tasks(marker=full_ids[0], limit=1) actual_ids = [i.task_id for i in marked_tasks] self.assertEqual(actual_ids, full_ids[1:2]) def test_sorted_list(self): tasks = self.task_repo.list_tasks(sort_key='status', sort_dir='desc') task_ids = [i.task_id for i in tasks] self.assertEqual([UUID2, UUID1, UUID3], task_ids) def test_add_task(self): task_type = 'import' task = self.task_factory.new_task(task_type, None) self.assertEqual(task.updated_at, task.created_at) task_details = self.task_factory.new_task_details(task.task_id, self.fake_task_input) self.task_repo.add(task, task_details) retrieved_task, retrieved_task_details = \ self.task_repo.get_task_and_details(task.task_id) self.assertEqual(retrieved_task.updated_at, task.updated_at) self.assertEqual(retrieved_task_details.task_id, retrieved_task.task_id) self.assertEqual(retrieved_task_details.input, task_details.input) def test_save_task(self): task, task_details = self.task_repo.get_task_and_details(UUID1) original_update_time = task.updated_at self.task_repo.save(task) current_update_time = task.updated_at self.assertTrue(current_update_time > original_update_time) task, task_details = self.task_repo.get_task_and_details(UUID1) self.assertEqual(task.updated_at, current_update_time) def test_remove_task(self): task, task_details = self.task_repo.get_task_and_details(UUID1) self.task_repo.remove(task) self.assertRaises(exception.NotFound, self.task_repo.get_task_and_details, task.task_id) glance-2014.1/glance/tests/unit/test_scrubber.py0000664000175400017540000000507312323736226022775 0ustar jenkinsjenkins00000000000000# Copyright 2013 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. import os import shutil import tempfile import uuid import eventlet import mox from glance.common import exception from glance import scrubber import glance.store from glance.tests import utils as test_utils class TestScrubber(test_utils.BaseTestCase): def setUp(self): self.data_dir = tempfile.mkdtemp() self.config(scrubber_datadir=self.data_dir) self.config(default_store='file') glance.store.create_stores() self.mox = mox.Mox() super(TestScrubber, self).setUp() def tearDown(self): self.mox.UnsetStubs() shutil.rmtree(self.data_dir) # These globals impact state outside of this test class, kill them. scrubber._file_queue = None scrubber._db_queue = None super(TestScrubber, self).tearDown() def _scrubber_cleanup_with_store_delete_exception(self, ex): fname = lambda: str(uuid.uuid4()) uri = 'file://some/path/%s' % (fname) id = 'helloworldid' scrub = scrubber.Scrubber(glance.store) scrub.registry = self.mox.CreateMockAnything() scrub.registry.get_image(id).AndReturn({'status': 'pending_delete'}) scrub.registry.update_image(id, {'status': 'deleted'}) self.mox.StubOutWithMock(glance.store, "delete_from_backend") glance.store.delete_from_backend( mox.IgnoreArg(), uri).AndRaise(ex) self.mox.ReplayAll() scrub._scrub_image(eventlet.greenpool.GreenPool(1), id, [(id, uri)]) self.mox.VerifyAll() q_path = os.path.join(self.data_dir, id) self.assertFalse(os.path.exists(q_path)) def test_store_delete_unsupported_backend_exception(self): ex = glance.store.UnsupportedBackend() self._scrubber_cleanup_with_store_delete_exception(ex) def test_store_delete_notfound_exception(self): ex = exception.NotFound() self._scrubber_cleanup_with_store_delete_exception(ex) glance-2014.1/glance/tests/unit/common/0000775000175400017540000000000012323736427021043 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/tests/unit/common/test_config.py0000664000175400017540000000724612323736226023727 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import os.path import shutil import fixtures import stubout from glance.api.middleware import context from glance.common import config from glance.tests import utils as test_utils class TestPasteApp(test_utils.BaseTestCase): def setUp(self): super(TestPasteApp, self).setUp() self.stubs = stubout.StubOutForTesting() self.addCleanup(self.stubs.UnsetAll) def _do_test_load_paste_app(self, expected_app_type, make_paste_file=True, paste_flavor=None, paste_config_file=None, paste_append=None): def _writeto(path, str): with open(path, 'wb') as f: f.write(str or '') f.flush() def _appendto(orig, copy, str): shutil.copy(orig, copy) with open(copy, 'ab') as f: f.write(str or '') f.flush() self.config(flavor=paste_flavor, config_file=paste_config_file, group='paste_deploy') temp_dir = self.useFixture(fixtures.TempDir()).path temp_file = os.path.join(temp_dir, 'testcfg.conf') _writeto(temp_file, '[DEFAULT]\n') config.parse_args(['--config-file', temp_file]) paste_to = temp_file.replace('.conf', '-paste.ini') if not paste_config_file and make_paste_file: paste_from = os.path.join(os.getcwd(), 'etc/glance-registry-paste.ini') _appendto(paste_from, paste_to, paste_append) app = config.load_paste_app('glance-registry') self.assertIsInstance(app, expected_app_type) def test_load_paste_app(self): expected_middleware = context.UnauthenticatedContextMiddleware self._do_test_load_paste_app(expected_middleware) def test_load_paste_app_paste_config_not_found(self): expected_middleware = context.UnauthenticatedContextMiddleware self.assertRaises(RuntimeError, self._do_test_load_paste_app, expected_middleware, make_paste_file=False) def test_load_paste_app_with_paste_flavor(self): pipeline = ('[pipeline:glance-registry-incomplete]\n' 'pipeline = context registryapp') expected_middleware = context.ContextMiddleware self._do_test_load_paste_app(expected_middleware, paste_flavor='incomplete', paste_append=pipeline) def test_load_paste_app_with_paste_config_file(self): paste_config_file = os.path.join(os.getcwd(), 'etc/glance-registry-paste.ini') expected_middleware = context.UnauthenticatedContextMiddleware self._do_test_load_paste_app(expected_middleware, paste_config_file=paste_config_file) def test_get_path_non_exist(self): self.assertRaises(RuntimeError, config._get_deployment_config_file) glance-2014.1/glance/tests/unit/common/test_location_strategy.py0000664000175400017540000002127612323736226026213 0ustar jenkinsjenkins00000000000000# Copyright 2014 IBM Corp. # 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 copy import stevedore from glance.common import location_strategy from glance.common.location_strategy import location_order from glance.common.location_strategy import store_type from glance.tests.unit import base class TestLocationStrategy(base.IsolatedUnitTest): """Test routines in glance.common.location_strategy""" def _set_original_strategies(self, original_strategies): for name in location_strategy._available_strategies.keys(): if name not in original_strategies: del location_strategy._available_strategies[name] def setUp(self): super(TestLocationStrategy, self).setUp() original_strategies = ['location_order', 'store_type'] self.addCleanup(self._set_original_strategies, original_strategies) def test_load_strategy_modules(self): modules = location_strategy._load_strategies() # By default we have two built-in strategy modules. self.assertEqual(len(modules), 2) self.assertEqual(set(modules.keys()), set(['location_order', 'store_type'])) self.assertEqual(location_strategy._available_strategies, modules) def test_load_strategy_module_with_deduplicating(self): modules = ['module1', 'module2'] def _fake_stevedore_extension_manager(*args, **kwargs): ret = lambda: None ret.names = lambda: modules return ret def _fake_stevedore_driver_manager(*args, **kwargs): ret = lambda: None ret.driver = lambda: None ret.driver.__name__ = kwargs['name'] # Module 1 and 2 has a same strategy name ret.driver.get_strategy_name = lambda: 'module_name' ret.driver.init = lambda: None return ret self.stub = self.stubs.Set(stevedore.extension, "ExtensionManager", _fake_stevedore_extension_manager) self.stub = self.stubs.Set(stevedore.driver, "DriverManager", _fake_stevedore_driver_manager) loaded_modules = location_strategy._load_strategies() self.assertEqual(len(loaded_modules), 1) self.assertEqual(loaded_modules.keys()[0], 'module_name') # Skipped module #2, duplicated one. self.assertEqual(loaded_modules['module_name'].__name__, 'module1') def test_load_strategy_module_with_init_exception(self): modules = ['module_init_exception', 'module_good'] def _fake_stevedore_extension_manager(*args, **kwargs): ret = lambda: None ret.names = lambda: modules return ret def _fake_stevedore_driver_manager(*args, **kwargs): if kwargs['name'] == 'module_init_exception': raise Exception('strategy module failed to initialize.') else: ret = lambda: None ret.driver = lambda: None ret.driver.__name__ = kwargs['name'] ret.driver.get_strategy_name = lambda: kwargs['name'] ret.driver.init = lambda: None return ret self.stub = self.stubs.Set(stevedore.extension, "ExtensionManager", _fake_stevedore_extension_manager) self.stub = self.stubs.Set(stevedore.driver, "DriverManager", _fake_stevedore_driver_manager) loaded_modules = location_strategy._load_strategies() self.assertEqual(len(loaded_modules), 1) self.assertEqual(loaded_modules.keys()[0], 'module_good') # Skipped module #1, initialize failed one. self.assertEqual(loaded_modules['module_good'].__name__, 'module_good') def test_verify_valid_location_strategy(self): for strategy_name in ['location_order', 'store_type']: self.config(location_strategy=strategy_name) location_strategy.verify_location_strategy() def test_verify_invalid_location_strategy(self): strategy = 'invalid_strategy' self.config(location_strategy=strategy) self.assertRaises(RuntimeError, location_strategy.verify_location_strategy, strategy) def test_get_ordered_locations_with_none_or_empty_locations(self): self.assertEqual(location_strategy.get_ordered_locations(None), []) self.assertEqual(location_strategy.get_ordered_locations([]), []) def test_get_ordered_locations(self): self.config(location_strategy='location_order') original_locs = [{'url': 'loc1'}, {'url': 'loc2'}] ordered_locs = location_strategy.get_ordered_locations(original_locs) # Original location list should remain unchanged self.assertNotEqual(id(original_locs), id(ordered_locs)) self.assertEqual(original_locs, ordered_locs) def test_choose_best_location_with_none_or_empty_locations(self): self.assertIsNone(location_strategy.choose_best_location(None)) self.assertIsNone(location_strategy.choose_best_location([])) def test_choose_best_location(self): self.config(location_strategy='location_order') original_locs = [{'url': 'loc1'}, {'url': 'loc2'}] best_loc = location_strategy.choose_best_location(original_locs) # Deep copy protect original location. self.assertNotEqual(id(original_locs), id(best_loc)) self.assertEqual(original_locs[0], best_loc) class TestLocationOrderStrategyModule(base.IsolatedUnitTest): """Test routines in glance.common.location_strategy.location_order""" def test_get_ordered_locations(self): original_locs = [{'url': 'loc1'}, {'url': 'loc2'}] ordered_locs = location_order.get_ordered_locations(original_locs) # The result will ordered by original natural order. self.assertEqual(original_locs, ordered_locs) class TestStoreTypeStrategyModule(base.IsolatedUnitTest): """Test routines in glance.common.location_strategy.store_type""" def test_get_ordered_locations(self): self.config(store_type_preference=[' rbd', 'sheepdog ', ' filesystem', 'swift ', ' http ', 's3'], group='store_type_location_strategy') locs = [{'url': 'file://image0', 'metadata': {'idx': 3}}, {'url': 'rbd://image1', 'metadata': {'idx': 0}}, {'url': 's3://image2', 'metadata': {'idx': 7}}, {'url': 'file://image3', 'metadata': {'idx': 4}}, {'url': 'swift://image4', 'metadata': {'idx': 6}}, {'url': 'cinder://image5', 'metadata': {'idx': 8}}, {'url': 'file://image6', 'metadata': {'idx': 5}}, {'url': 'rbd://image7', 'metadata': {'idx': 1}}, {'url': 'sheepdog://image8', 'metadata': {'idx': 2}}] ordered_locs = store_type.get_ordered_locations(copy.deepcopy(locs)) locs.sort(key=lambda loc: loc['metadata']['idx']) # The result will ordered by preferred store type order. self.assertEqual(ordered_locs, locs) def test_get_ordered_locations_with_invalid_store_name(self): self.config(store_type_preference=[' rbd', 'sheepdog ', 'invalid', 'swift ', ' http ', 's3'], group='store_type_location_strategy') locs = [{'url': 'file://image0', 'metadata': {'idx': 5}}, {'url': 'rbd://image1', 'metadata': {'idx': 0}}, {'url': 's3://image2', 'metadata': {'idx': 4}}, {'url': 'file://image3', 'metadata': {'idx': 6}}, {'url': 'swift://image4', 'metadata': {'idx': 3}}, {'url': 'cinder://image5', 'metadata': {'idx': 7}}, {'url': 'file://image6', 'metadata': {'idx': 8}}, {'url': 'rbd://image7', 'metadata': {'idx': 1}}, {'url': 'sheepdog://image8', 'metadata': {'idx': 2}}] ordered_locs = store_type.get_ordered_locations(copy.deepcopy(locs)) locs.sort(key=lambda loc: loc['metadata']['idx']) # The result will ordered by preferred store type order. self.assertEqual(ordered_locs, locs) glance-2014.1/glance/tests/unit/common/test_wsgi.py0000664000175400017540000004653712323736226023441 0ustar jenkinsjenkins00000000000000# Copyright 2010-2011 OpenStack Foundation # Copyright 2014 IBM Corp. # 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 datetime import socket from babel import localedata import eventlet.patcher import fixtures import gettext import mock import webob from glance.common import exception from glance.common import utils from glance.common import wsgi from glance.openstack.common import gettextutils from glance.tests import utils as test_utils class RequestTest(test_utils.BaseTestCase): def _set_expected_languages(self, all_locales=[], avail_locales=None): # Override localedata.locale_identifiers to return some locales. def returns_some_locales(*args, **kwargs): return all_locales self.stubs.Set(localedata, 'locale_identifiers', returns_some_locales) # Override gettext.find to return other than None for some languages. def fake_gettext_find(lang_id, *args, **kwargs): found_ret = '/glance/%s/LC_MESSAGES/glance.mo' % lang_id if avail_locales is None: # All locales are available. return found_ret languages = kwargs['languages'] if languages[0] in avail_locales: return found_ret return None self.stubs.Set(gettext, 'find', fake_gettext_find) def test_content_type_missing(self): request = wsgi.Request.blank('/tests/123') self.assertRaises(exception.InvalidContentType, request.get_content_type, ('application/xml',)) def test_content_type_unsupported(self): request = wsgi.Request.blank('/tests/123') request.headers["Content-Type"] = "text/html" self.assertRaises(exception.InvalidContentType, request.get_content_type, ('application/xml',)) def test_content_type_with_charset(self): request = wsgi.Request.blank('/tests/123') request.headers["Content-Type"] = "application/json; charset=UTF-8" result = request.get_content_type(('application/json',)) self.assertEqual(result, "application/json") def test_content_type_from_accept_xml(self): request = wsgi.Request.blank('/tests/123') request.headers["Accept"] = "application/xml" result = request.best_match_content_type() self.assertEqual(result, "application/json") def test_content_type_from_accept_json(self): request = wsgi.Request.blank('/tests/123') request.headers["Accept"] = "application/json" result = request.best_match_content_type() self.assertEqual(result, "application/json") def test_content_type_from_accept_xml_json(self): request = wsgi.Request.blank('/tests/123') request.headers["Accept"] = "application/xml, application/json" result = request.best_match_content_type() self.assertEqual(result, "application/json") def test_content_type_from_accept_json_xml_quality(self): request = wsgi.Request.blank('/tests/123') request.headers["Accept"] = ("application/json; q=0.3, " "application/xml; q=0.9") result = request.best_match_content_type() self.assertEqual(result, "application/json") def test_content_type_accept_default(self): request = wsgi.Request.blank('/tests/123.unsupported') request.headers["Accept"] = "application/unsupported1" result = request.best_match_content_type() self.assertEqual(result, "application/json") def test_language_accept_default(self): request = wsgi.Request.blank('/tests/123') request.headers["Accept-Language"] = "zz-ZZ,zz;q=0.8" result = request.best_match_language() self.assertIsNone(result) def test_language_accept_none(self): request = wsgi.Request.blank('/tests/123') result = request.best_match_language() self.assertIsNone(result) def test_best_match_language_expected(self): # If Accept-Language is a supported language, best_match_language() # returns it. self._set_expected_languages(all_locales=['it']) req = wsgi.Request.blank('/', headers={'Accept-Language': 'it'}) self.assertEqual('it', req.best_match_language()) def test_request_match_language_unexpected(self): # If Accept-Language is a language we do not support, # best_match_language() returns None. self._set_expected_languages(all_locales=['it']) req = wsgi.Request.blank('/', headers={'Accept-Language': 'zh'}) self.assertIsNone(req.best_match_language()) @mock.patch.object(webob.acceptparse.AcceptLanguage, 'best_match') def test_best_match_language_unknown(self, mock_best_match): # Test that we are actually invoking language negotiation by webop request = wsgi.Request.blank('/') accepted = 'unknown-lang' request.headers = {'Accept-Language': accepted} mock_best_match.return_value = None self.assertIsNone(request.best_match_language()) # If Accept-Language is missing or empty, match should be None request.headers = {'Accept-Language': ''} self.assertIsNone(request.best_match_language()) request.headers.pop('Accept-Language') self.assertIsNone(request.best_match_language()) class ResourceTest(test_utils.BaseTestCase): def test_get_action_args(self): env = { 'wsgiorg.routing_args': [ None, { 'controller': None, 'format': None, 'action': 'update', 'id': 12, }, ], } expected = {'action': 'update', 'id': 12} actual = wsgi.Resource(None, None, None).get_action_args(env) self.assertEqual(actual, expected) def test_get_action_args_invalid_index(self): env = {'wsgiorg.routing_args': []} expected = {} actual = wsgi.Resource(None, None, None).get_action_args(env) self.assertEqual(actual, expected) def test_get_action_args_del_controller_error(self): actions = {'format': None, 'action': 'update', 'id': 12} env = {'wsgiorg.routing_args': [None, actions]} expected = {'action': 'update', 'id': 12} actual = wsgi.Resource(None, None, None).get_action_args(env) self.assertEqual(actual, expected) def test_get_action_args_del_format_error(self): actions = {'action': 'update', 'id': 12} env = {'wsgiorg.routing_args': [None, actions]} expected = {'action': 'update', 'id': 12} actual = wsgi.Resource(None, None, None).get_action_args(env) self.assertEqual(actual, expected) def test_dispatch(self): class Controller(object): def index(self, shirt, pants=None): return (shirt, pants) resource = wsgi.Resource(None, None, None) actual = resource.dispatch(Controller(), 'index', 'on', pants='off') expected = ('on', 'off') self.assertEqual(actual, expected) def test_dispatch_default(self): class Controller(object): def default(self, shirt, pants=None): return (shirt, pants) resource = wsgi.Resource(None, None, None) actual = resource.dispatch(Controller(), 'index', 'on', pants='off') expected = ('on', 'off') self.assertEqual(actual, expected) def test_dispatch_no_default(self): class Controller(object): def show(self, shirt, pants=None): return (shirt, pants) resource = wsgi.Resource(None, None, None) self.assertRaises(AttributeError, resource.dispatch, Controller(), 'index', 'on', pants='off') def test_call(self): class FakeController(object): def index(self, shirt, pants=None): return (shirt, pants) resource = wsgi.Resource(FakeController(), None, None) def dispatch(self, obj, action, *args, **kwargs): if isinstance(obj, wsgi.JSONRequestDeserializer): return [] if isinstance(obj, wsgi.JSONResponseSerializer): raise webob.exc.HTTPForbidden() self.stubs.Set(wsgi.Resource, 'dispatch', dispatch) request = wsgi.Request.blank('/') response = resource.__call__(request) self.assertIsInstance(response, webob.exc.HTTPForbidden) self.assertEqual(response.status_code, 403) @mock.patch.object(wsgi, 'translate_exception') def test_resource_call_error_handle_localized(self, mock_translate_exception): class Controller(object): def delete(self, req, identity): raise webob.exc.HTTPBadRequest(explanation='Not Found') actions = {'action': 'delete', 'identity': 12} env = {'wsgiorg.routing_args': [None, actions]} request = wsgi.Request.blank('/tests/123', environ=env) message_es = 'No Encontrado' resource = wsgi.Resource(Controller(), wsgi.JSONRequestDeserializer(), None) translated_exc = webob.exc.HTTPBadRequest(message_es) mock_translate_exception.return_value = translated_exc e = self.assertRaises(webob.exc.HTTPBadRequest, resource, request) self.assertEqual(message_es, str(e)) @mock.patch.object(webob.acceptparse.AcceptLanguage, 'best_match') @mock.patch.object(gettextutils, 'translate') def test_translate_exception(self, mock_translate, mock_best_match): mock_translate.return_value = 'No Encontrado' mock_best_match.return_value = 'de' req = wsgi.Request.blank('/tests/123') req.headers["Accept-Language"] = "de" e = webob.exc.HTTPNotFound(explanation='Not Found') e = wsgi.translate_exception(req, e) self.assertEqual('No Encontrado', e.explanation) class JSONResponseSerializerTest(test_utils.BaseTestCase): def test_to_json(self): fixture = {"key": "value"} expected = '{"key": "value"}' actual = wsgi.JSONResponseSerializer().to_json(fixture) self.assertEqual(actual, expected) def test_to_json_with_date_format_value(self): fixture = {"date": datetime.datetime(1, 3, 8, 2)} expected = '{"date": "0001-03-08T02:00:00"}' actual = wsgi.JSONResponseSerializer().to_json(fixture) self.assertEqual(actual, expected) def test_to_json_with_more_deep_format(self): fixture = {"is_public": True, "name": [{"name1": "test"}]} expected = '{"is_public": true, "name": [{"name1": "test"}]}' actual = wsgi.JSONResponseSerializer().to_json(fixture) self.assertEqual(actual, expected) def test_to_json_with_set(self): fixture = set(["foo"]) expected = '["foo"]' actual = wsgi.JSONResponseSerializer().to_json(fixture) self.assertEqual(actual, expected) def test_default(self): fixture = {"key": "value"} response = webob.Response() wsgi.JSONResponseSerializer().default(response, fixture) self.assertEqual(response.status_int, 200) content_types = filter(lambda h: h[0] == 'Content-Type', response.headerlist) self.assertEqual(len(content_types), 1) self.assertEqual(response.content_type, 'application/json') self.assertEqual(response.body, '{"key": "value"}') class JSONRequestDeserializerTest(test_utils.BaseTestCase): def test_has_body_no_content_length(self): request = wsgi.Request.blank('/') request.method = 'POST' request.body = 'asdf' request.headers.pop('Content-Length') self.assertFalse(wsgi.JSONRequestDeserializer().has_body(request)) def test_has_body_zero_content_length(self): request = wsgi.Request.blank('/') request.method = 'POST' request.body = 'asdf' request.headers['Content-Length'] = 0 self.assertFalse(wsgi.JSONRequestDeserializer().has_body(request)) def test_has_body_has_content_length(self): request = wsgi.Request.blank('/') request.method = 'POST' request.body = 'asdf' self.assertTrue('Content-Length' in request.headers) self.assertTrue(wsgi.JSONRequestDeserializer().has_body(request)) def test_no_body_no_content_length(self): request = wsgi.Request.blank('/') self.assertFalse(wsgi.JSONRequestDeserializer().has_body(request)) def test_from_json(self): fixture = '{"key": "value"}' expected = {"key": "value"} actual = wsgi.JSONRequestDeserializer().from_json(fixture) self.assertEqual(actual, expected) def test_from_json_malformed(self): fixture = 'kjasdklfjsklajf' self.assertRaises(webob.exc.HTTPBadRequest, wsgi.JSONRequestDeserializer().from_json, fixture) def test_default_no_body(self): request = wsgi.Request.blank('/') actual = wsgi.JSONRequestDeserializer().default(request) expected = {} self.assertEqual(actual, expected) def test_default_with_body(self): request = wsgi.Request.blank('/') request.method = 'POST' request.body = '{"key": "value"}' actual = wsgi.JSONRequestDeserializer().default(request) expected = {"body": {"key": "value"}} self.assertEqual(actual, expected) def test_has_body_has_transfer_encoding(self): request = wsgi.Request.blank('/') request.method = 'POST' request.body = 'fake_body' request.headers['transfer-encoding'] = 0 self.assertTrue('transfer-encoding' in request.headers) self.assertTrue(wsgi.JSONRequestDeserializer().has_body(request)) def test_get_bind_addr_default_value(self): expected = ('0.0.0.0', '123456') actual = wsgi.get_bind_addr(default_port="123456") self.assertEqual(expected, actual) class ServerTest(test_utils.BaseTestCase): def test_create_pool(self): """Ensure the wsgi thread pool is an eventlet.greenpool.GreenPool.""" actual = wsgi.Server(threads=1).create_pool() self.assertIsInstance(actual, eventlet.greenpool.GreenPool) class TestHelpers(test_utils.BaseTestCase): def test_headers_are_unicode(self): """ Verifies that the headers returned by conversion code are unicode. Headers are passed via http in non-testing mode, which automatically converts them to unicode. Verifying that the method does the conversion proves that we aren't passing data that works in tests but will fail in production. """ fixture = {'name': 'fake public image', 'is_public': True, 'size': 19, 'location': "file:///tmp/glance-tests/2", 'properties': {'distro': 'Ubuntu 10.04 LTS'}} headers = utils.image_meta_to_http_headers(fixture) for k, v in headers.iteritems(): self.assertIsInstance(v, unicode) def test_data_passed_properly_through_headers(self): """ Verifies that data is the same after being passed through headers """ fixture = {'name': 'fake public image', 'is_public': True, 'deleted': False, 'name': None, 'size': 19, 'location': "file:///tmp/glance-tests/2", 'properties': {'distro': 'Ubuntu 10.04 LTS'}} headers = utils.image_meta_to_http_headers(fixture) class FakeResponse(): pass response = FakeResponse() response.headers = headers result = utils.get_image_meta_from_headers(response) for k, v in fixture.iteritems(): if v is not None: self.assertEqual(v, result[k]) else: self.assertFalse(k in result) class GetSocketTestCase(test_utils.BaseTestCase): def setUp(self): super(GetSocketTestCase, self).setUp() self.useFixture(fixtures.MonkeyPatch( "glance.common.wsgi.get_bind_addr", lambda x: ('192.168.0.13', 1234))) addr_info_list = [(2, 1, 6, '', ('192.168.0.13', 80)), (2, 2, 17, '', ('192.168.0.13', 80)), (2, 3, 0, '', ('192.168.0.13', 80))] self.useFixture(fixtures.MonkeyPatch( "glance.common.wsgi.socket.getaddrinfo", lambda *x: addr_info_list)) self.useFixture(fixtures.MonkeyPatch( "glance.common.wsgi.time.time", mock.Mock(side_effect=[0, 1, 5, 10, 20, 35]))) self.useFixture(fixtures.MonkeyPatch( "glance.common.wsgi.utils.validate_key_cert", lambda *x: None)) wsgi.CONF.cert_file = '/etc/ssl/cert' wsgi.CONF.key_file = '/etc/ssl/key' wsgi.CONF.ca_file = '/etc/ssl/ca_cert' wsgi.CONF.tcp_keepidle = 600 def test_correct_get_socket(self): mock_socket = mock.Mock() self.useFixture(fixtures.MonkeyPatch( 'glance.common.wsgi.ssl.wrap_socket', mock_socket)) self.useFixture(fixtures.MonkeyPatch( 'glance.common.wsgi.eventlet.listen', lambda *x, **y: None)) wsgi.get_socket(1234) self.assertTrue(mock.call().setsockopt( socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) in mock_socket.mock_calls) self.assertTrue(mock.call().setsockopt( socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) in mock_socket.mock_calls) if hasattr(socket, 'TCP_KEEPIDLE'): self.assertTrue(mock.call().setsockopt( socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, wsgi.CONF.tcp_keepidle) in mock_socket.mock_calls) def test_get_socket_without_all_ssl_reqs(self): wsgi.CONF.key_file = None self.assertRaises(RuntimeError, wsgi.get_socket, 1234) def test_get_socket_with_bind_problems(self): self.useFixture(fixtures.MonkeyPatch( 'glance.common.wsgi.eventlet.listen', mock.Mock(side_effect=( [wsgi.socket.error(socket.errno.EADDRINUSE)] * 3 + [None])))) self.useFixture(fixtures.MonkeyPatch( 'glance.common.wsgi.ssl.wrap_socket', lambda *x, **y: None)) self.assertRaises(RuntimeError, wsgi.get_socket, 1234) def test_get_socket_with_unexpected_socket_errno(self): self.useFixture(fixtures.MonkeyPatch( 'glance.common.wsgi.eventlet.listen', mock.Mock(side_effect=wsgi.socket.error(socket.errno.ENOMEM)))) self.useFixture(fixtures.MonkeyPatch( 'glance.common.wsgi.ssl.wrap_socket', lambda *x, **y: None)) self.assertRaises(wsgi.socket.error, wsgi.get_socket, 1234) glance-2014.1/glance/tests/unit/common/test_client.py0000664000175400017540000000561212323736226023733 0ustar jenkinsjenkins00000000000000# Copyright 2013 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. import httplib import mox import testtools from glance.common import auth from glance.common import client from glance.tests import utils class TestClient(testtools.TestCase): def setUp(self): super(TestClient, self).setUp() self.mock = mox.Mox() self.mock.StubOutWithMock(httplib.HTTPConnection, 'request') self.mock.StubOutWithMock(httplib.HTTPConnection, 'getresponse') self.endpoint = 'example.com' self.client = client.BaseClient(self.endpoint, port=9191, auth_tok=u'abc123') def tearDown(self): super(TestClient, self).tearDown() self.mock.UnsetStubs() def test_make_auth_plugin(self): creds = {'strategy': 'keystone'} insecure = False configure_via_auth = True self.mock.StubOutWithMock(auth, 'get_plugin_from_strategy') auth.get_plugin_from_strategy('keystone', creds, insecure, configure_via_auth) self.mock.ReplayAll() self.client.make_auth_plugin(creds, insecure) self.mock.VerifyAll() def test_http_encoding_headers(self): httplib.HTTPConnection.request( mox.IgnoreArg(), mox.IgnoreArg(), mox.IgnoreArg(), mox.IgnoreArg()) # Lets fake the response # returned by httplib fake = utils.FakeHTTPResponse(data="Ok") httplib.HTTPConnection.getresponse().AndReturn(fake) self.mock.ReplayAll() headers = {"test": u'ni\xf1o'} resp = self.client.do_request('GET', '/v1/images/detail', headers=headers) self.assertEqual(resp, fake) def test_http_encoding_params(self): httplib.HTTPConnection.request( mox.IgnoreArg(), mox.IgnoreArg(), mox.IgnoreArg(), mox.IgnoreArg()) # Lets fake the response # returned by httplib fake = utils.FakeHTTPResponse(data="Ok") httplib.HTTPConnection.getresponse().AndReturn(fake) self.mock.ReplayAll() params = {"test": u'ni\xf1o'} resp = self.client.do_request('GET', '/v1/images/detail', params=params) self.assertEqual(resp, fake) glance-2014.1/glance/tests/unit/common/test_exception.py0000664000175400017540000000342412323736226024452 0ustar jenkinsjenkins00000000000000# Copyright 2012 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import six from glance.common import exception from glance.tests import utils as test_utils class GlanceExceptionTestCase(test_utils.BaseTestCase): def test_default_error_msg(self): class FakeGlanceException(exception.GlanceException): message = "default message" exc = FakeGlanceException() self.assertEqual(unicode(exc), 'default message') def test_specified_error_msg(self): self.assertTrue('test' in unicode(exception.GlanceException('test'))) def test_default_error_msg_with_kwargs(self): class FakeGlanceException(exception.GlanceException): message = "default message: %(code)s" exc = FakeGlanceException(code=500) self.assertEqual(unicode(exc), "default message: 500") def test_specified_error_msg_with_kwargs(self): self.assertTrue('test: 500' in unicode(exception.GlanceException('test: %(code)s', code=500))) def test_non_unicode_error_msg(self): exc = exception.GlanceException(str('test')) self.assertIsInstance(six.text_type(exc), six.text_type) glance-2014.1/glance/tests/unit/common/test_property_utils.py0000664000175400017540000005572212323736226025570 0ustar jenkinsjenkins00000000000000# Copyright 2013 OpenStack Foundation. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from six.moves import xrange from glance.api import policy from glance.common import exception from glance.common import property_utils import glance.context from glance.tests.unit import base CONFIG_SECTIONS = [ '^x_owner_.*', 'spl_create_prop', 'spl_read_prop', 'spl_read_only_prop', 'spl_update_prop', 'spl_update_only_prop', 'spl_delete_prop', '^x_all_permitted.*', '^x_none_permitted.*', 'x_none_read', 'x_none_update', 'x_none_delete', 'x_foo_matcher', 'x_foo_*', '.*' ] def create_context(policy, roles=[]): return glance.context.RequestContext(roles=roles, policy_enforcer=policy) class TestPropertyRulesWithRoles(base.IsolatedUnitTest): def setUp(self): super(TestPropertyRulesWithRoles, self).setUp() self.set_property_protections() self.policy = policy.Enforcer() def tearDown(self): super(TestPropertyRulesWithRoles, self).tearDown() def test_is_property_protections_enabled_true(self): self.config(property_protection_file="property-protections.conf") self.assertTrue(property_utils.is_property_protection_enabled()) def test_is_property_protections_enabled_false(self): self.config(property_protection_file=None) self.assertFalse(property_utils.is_property_protection_enabled()) def test_property_protection_file_doesnt_exist(self): self.config(property_protection_file='fake-file.conf') self.assertRaises(exception.InvalidPropertyProtectionConfiguration, property_utils.PropertyRules) def test_property_protection_with_mutually_exclusive_rule(self): exclusive_rules = {'.*': {'create': ['@', '!'], 'read': ['fake-role'], 'update': ['fake-role'], 'delete': ['fake-role']}} self.set_property_protection_rules(exclusive_rules) self.assertRaises(exception.InvalidPropertyProtectionConfiguration, property_utils.PropertyRules) def test_property_protection_with_malformed_rule(self): malformed_rules = {'^[0-9)': {'create': ['fake-role'], 'read': ['fake-role'], 'update': ['fake-role'], 'delete': ['fake-role']}} self.set_property_protection_rules(malformed_rules) self.assertRaises(exception.InvalidPropertyProtectionConfiguration, property_utils.PropertyRules) def test_property_protection_with_missing_operation(self): rules_with_missing_operation = {'^[0-9]': {'create': ['fake-role'], 'update': ['fake-role'], 'delete': ['fake-role']}} self.set_property_protection_rules(rules_with_missing_operation) self.assertRaises(exception.InvalidPropertyProtectionConfiguration, property_utils.PropertyRules) def test_property_protection_with_misspelt_operation(self): rules_with_misspelt_operation = {'^[0-9]': {'create': ['fake-role'], 'rade': ['fake-role'], 'update': ['fake-role'], 'delete': ['fake-role']}} self.set_property_protection_rules(rules_with_misspelt_operation) self.assertRaises(exception.InvalidPropertyProtectionConfiguration, property_utils.PropertyRules) def test_property_protection_with_whitespace(self): rules_whitespace = { '^test_prop.*': { 'create': ['member ,fake-role'], 'read': ['fake-role, member'], 'update': ['fake-role, member'], 'delete': ['fake-role, member'] } } self.set_property_protection_rules(rules_whitespace) self.rules_checker = property_utils.PropertyRules() self.assertTrue(self.rules_checker.check_property_rules('test_prop_1', 'read', create_context(self.policy, ['member']))) self.assertTrue(self.rules_checker.check_property_rules('test_prop_1', 'read', create_context(self.policy, ['fake-role']))) def test_check_property_rules_invalid_action(self): self.rules_checker = property_utils.PropertyRules(self.policy) self.assertFalse(self.rules_checker.check_property_rules('test_prop', 'hall', create_context(self.policy, ['admin']))) def test_check_property_rules_read_permitted_admin_role(self): self.rules_checker = property_utils.PropertyRules(self.policy) self.assertTrue(self.rules_checker.check_property_rules('test_prop', 'read', create_context(self.policy, ['admin']))) def test_check_property_rules_read_permitted_specific_role(self): self.rules_checker = property_utils.PropertyRules(self.policy) self.assertTrue(self.rules_checker.check_property_rules( 'x_owner_prop', 'read', create_context(self.policy, ['member']))) def test_check_property_rules_read_unpermitted_role(self): self.rules_checker = property_utils.PropertyRules(self.policy) self.assertFalse(self.rules_checker.check_property_rules('test_prop', 'read', create_context(self.policy, ['member']))) def test_check_property_rules_create_permitted_admin_role(self): self.rules_checker = property_utils.PropertyRules(self.policy) self.assertTrue(self.rules_checker.check_property_rules('test_prop', 'create', create_context(self.policy, ['admin']))) def test_check_property_rules_create_permitted_specific_role(self): self.rules_checker = property_utils.PropertyRules(self.policy) self.assertTrue(self.rules_checker.check_property_rules( 'x_owner_prop', 'create', create_context(self.policy, ['member']))) def test_check_property_rules_create_unpermitted_role(self): self.rules_checker = property_utils.PropertyRules(self.policy) self.assertFalse(self.rules_checker.check_property_rules('test_prop', 'create', create_context(self.policy, ['member']))) def test_check_property_rules_update_permitted_admin_role(self): self.rules_checker = property_utils.PropertyRules(self.policy) self.assertTrue(self.rules_checker.check_property_rules('test_prop', 'update', create_context(self.policy, ['admin']))) def test_check_property_rules_update_permitted_specific_role(self): self.rules_checker = property_utils.PropertyRules(self.policy) self.assertTrue(self.rules_checker.check_property_rules( 'x_owner_prop', 'update', create_context(self.policy, ['member']))) def test_check_property_rules_update_unpermitted_role(self): self.rules_checker = property_utils.PropertyRules(self.policy) self.assertFalse(self.rules_checker.check_property_rules('test_prop', 'update', create_context(self.policy, ['member']))) def test_check_property_rules_delete_permitted_admin_role(self): self.rules_checker = property_utils.PropertyRules(self.policy) self.assertTrue(self.rules_checker.check_property_rules('test_prop', 'delete', create_context(self.policy, ['admin']))) def test_check_property_rules_delete_permitted_specific_role(self): self.rules_checker = property_utils.PropertyRules(self.policy) self.assertTrue(self.rules_checker.check_property_rules( 'x_owner_prop', 'delete', create_context(self.policy, ['member']))) def test_check_property_rules_delete_unpermitted_role(self): self.rules_checker = property_utils.PropertyRules(self.policy) self.assertFalse(self.rules_checker.check_property_rules('test_prop', 'delete', create_context(self.policy, ['member']))) def test_property_config_loaded_in_order(self): """ Verify the order of loaded config sections matches that from the configuration file """ self.rules_checker = property_utils.PropertyRules(self.policy) self.assertEqual(property_utils.CONFIG.sections(), CONFIG_SECTIONS) def test_property_rules_loaded_in_order(self): """ Verify rules are iterable in the same order as read from the config file """ self.rules_checker = property_utils.PropertyRules(self.policy) for i in xrange(len(property_utils.CONFIG.sections())): self.assertEqual(property_utils.CONFIG.sections()[i], self.rules_checker.rules[i][0].pattern) def test_check_property_rules_create_all_permitted(self): self.rules_checker = property_utils.PropertyRules() self.assertTrue(self.rules_checker.check_property_rules( 'x_all_permitted', 'create', create_context(self.policy, ['']))) def test_check_property_rules_read_all_permitted(self): self.rules_checker = property_utils.PropertyRules() self.assertTrue(self.rules_checker.check_property_rules( 'x_all_permitted', 'read', create_context(self.policy, ['']))) def test_check_property_rules_update_all_permitted(self): self.rules_checker = property_utils.PropertyRules() self.assertTrue(self.rules_checker.check_property_rules( 'x_all_permitted', 'update', create_context(self.policy, ['']))) def test_check_property_rules_delete_all_permitted(self): self.rules_checker = property_utils.PropertyRules() self.assertTrue(self.rules_checker.check_property_rules( 'x_all_permitted', 'delete', create_context(self.policy, ['']))) def test_check_property_rules_create_none_permitted(self): self.rules_checker = property_utils.PropertyRules() self.assertFalse(self.rules_checker.check_property_rules( 'x_none_permitted', 'create', create_context(self.policy, ['']))) def test_check_property_rules_read_none_permitted(self): self.rules_checker = property_utils.PropertyRules() self.assertFalse(self.rules_checker.check_property_rules( 'x_none_permitted', 'read', create_context(self.policy, ['']))) def test_check_property_rules_update_none_permitted(self): self.rules_checker = property_utils.PropertyRules() self.assertFalse(self.rules_checker.check_property_rules( 'x_none_permitted', 'update', create_context(self.policy, ['']))) def test_check_property_rules_delete_none_permitted(self): self.rules_checker = property_utils.PropertyRules() self.assertFalse(self.rules_checker.check_property_rules( 'x_none_permitted', 'delete', create_context(self.policy, ['']))) def test_check_property_rules_read_none(self): self.rules_checker = property_utils.PropertyRules() self.assertTrue(self.rules_checker.check_property_rules( 'x_none_read', 'create', create_context(self.policy, ['admin', 'member']))) self.assertFalse(self.rules_checker.check_property_rules( 'x_none_read', 'read', create_context(self.policy, ['']))) self.assertFalse(self.rules_checker.check_property_rules( 'x_none_read', 'update', create_context(self.policy, ['']))) self.assertFalse(self.rules_checker.check_property_rules( 'x_none_read', 'delete', create_context(self.policy, ['']))) def test_check_property_rules_update_none(self): self.rules_checker = property_utils.PropertyRules() self.assertTrue(self.rules_checker.check_property_rules( 'x_none_update', 'create', create_context(self.policy, ['admin', 'member']))) self.assertTrue(self.rules_checker.check_property_rules( 'x_none_update', 'read', create_context(self.policy, ['admin', 'member']))) self.assertFalse(self.rules_checker.check_property_rules( 'x_none_update', 'update', create_context(self.policy, ['']))) self.assertTrue(self.rules_checker.check_property_rules( 'x_none_update', 'delete', create_context(self.policy, ['admin', 'member']))) def test_check_property_rules_delete_none(self): self.rules_checker = property_utils.PropertyRules() self.assertTrue(self.rules_checker.check_property_rules( 'x_none_delete', 'create', create_context(self.policy, ['admin', 'member']))) self.assertTrue(self.rules_checker.check_property_rules( 'x_none_delete', 'read', create_context(self.policy, ['admin', 'member']))) self.assertTrue(self.rules_checker.check_property_rules( 'x_none_delete', 'update', create_context(self.policy, ['admin', 'member']))) self.assertFalse(self.rules_checker.check_property_rules( 'x_none_delete', 'delete', create_context(self.policy, ['']))) def test_check_return_first_match(self): self.rules_checker = property_utils.PropertyRules() self.assertFalse(self.rules_checker.check_property_rules( 'x_foo_matcher', 'create', create_context(self.policy, ['']))) self.assertFalse(self.rules_checker.check_property_rules( 'x_foo_matcher', 'read', create_context(self.policy, ['']))) self.assertFalse(self.rules_checker.check_property_rules( 'x_foo_matcher', 'update', create_context(self.policy, ['']))) self.assertFalse(self.rules_checker.check_property_rules( 'x_foo_matcher', 'delete', create_context(self.policy, ['']))) class TestPropertyRulesWithPolicies(base.IsolatedUnitTest): def setUp(self): super(TestPropertyRulesWithPolicies, self).setUp() self.set_property_protections(use_policies=True) self.policy = policy.Enforcer() self.rules_checker = property_utils.PropertyRules(self.policy) def tearDown(self): super(TestPropertyRulesWithPolicies, self).tearDown() def test_check_property_rules_create_permitted_specific_policy(self): self.assertTrue(self.rules_checker.check_property_rules( 'spl_creator_policy', 'create', create_context(self.policy, ['spl_role']))) def test_check_property_rules_create_unpermitted_policy(self): self.assertFalse(self.rules_checker.check_property_rules( 'spl_creator_policy', 'create', create_context(self.policy, ['fake-role']))) def test_check_property_rules_read_permitted_specific_policy(self): self.assertTrue(self.rules_checker.check_property_rules( 'spl_creator_policy', 'read', create_context(self.policy, ['spl_role']))) def test_check_property_rules_read_unpermitted_policy(self): self.assertFalse(self.rules_checker.check_property_rules( 'spl_creator_policy', 'read', create_context(self.policy, ['fake-role']))) def test_check_property_rules_update_permitted_specific_policy(self): self.assertTrue(self.rules_checker.check_property_rules( 'spl_creator_policy', 'update', create_context(self.policy, ['admin']))) def test_check_property_rules_update_unpermitted_policy(self): self.assertFalse(self.rules_checker.check_property_rules( 'spl_creator_policy', 'update', create_context(self.policy, ['fake-role']))) def test_check_property_rules_delete_permitted_specific_policy(self): self.assertTrue(self.rules_checker.check_property_rules( 'spl_creator_policy', 'delete', create_context(self.policy, ['admin']))) def test_check_property_rules_delete_unpermitted_policy(self): self.assertFalse(self.rules_checker.check_property_rules( 'spl_creator_policy', 'delete', create_context(self.policy, ['fake-role']))) def test_property_protection_with_malformed_rule(self): malformed_rules = {'^[0-9)': {'create': ['fake-policy'], 'read': ['fake-policy'], 'update': ['fake-policy'], 'delete': ['fake-policy']}} self.set_property_protection_rules(malformed_rules) self.assertRaises(exception.InvalidPropertyProtectionConfiguration, property_utils.PropertyRules) def test_property_protection_with_multiple_policies(self): malformed_rules = {'^x_.*': {'create': ['fake-policy, another_pol'], 'read': ['fake-policy'], 'update': ['fake-policy'], 'delete': ['fake-policy']}} self.set_property_protection_rules(malformed_rules) self.assertRaises(exception.InvalidPropertyProtectionConfiguration, property_utils.PropertyRules) def test_check_property_rules_create_all_permitted(self): self.rules_checker = property_utils.PropertyRules() self.assertTrue(self.rules_checker.check_property_rules( 'x_all_permitted', 'create', create_context(self.policy, ['']))) def test_check_property_rules_read_all_permitted(self): self.rules_checker = property_utils.PropertyRules() self.assertTrue(self.rules_checker.check_property_rules( 'x_all_permitted', 'read', create_context(self.policy, ['']))) def test_check_property_rules_update_all_permitted(self): self.rules_checker = property_utils.PropertyRules() self.assertTrue(self.rules_checker.check_property_rules( 'x_all_permitted', 'update', create_context(self.policy, ['']))) def test_check_property_rules_delete_all_permitted(self): self.rules_checker = property_utils.PropertyRules() self.assertTrue(self.rules_checker.check_property_rules( 'x_all_permitted', 'delete', create_context(self.policy, ['']))) def test_check_property_rules_create_none_permitted(self): self.rules_checker = property_utils.PropertyRules() self.assertFalse(self.rules_checker.check_property_rules( 'x_none_permitted', 'create', create_context(self.policy, ['']))) def test_check_property_rules_read_none_permitted(self): self.rules_checker = property_utils.PropertyRules() self.assertFalse(self.rules_checker.check_property_rules( 'x_none_permitted', 'read', create_context(self.policy, ['']))) def test_check_property_rules_update_none_permitted(self): self.rules_checker = property_utils.PropertyRules() self.assertFalse(self.rules_checker.check_property_rules( 'x_none_permitted', 'update', create_context(self.policy, ['']))) def test_check_property_rules_delete_none_permitted(self): self.rules_checker = property_utils.PropertyRules() self.assertFalse(self.rules_checker.check_property_rules( 'x_none_permitted', 'delete', create_context(self.policy, ['']))) def test_check_property_rules_read_none(self): self.rules_checker = property_utils.PropertyRules() self.assertTrue(self.rules_checker.check_property_rules( 'x_none_read', 'create', create_context(self.policy, ['admin', 'member']))) self.assertFalse(self.rules_checker.check_property_rules( 'x_none_read', 'read', create_context(self.policy, ['']))) self.assertFalse(self.rules_checker.check_property_rules( 'x_none_read', 'update', create_context(self.policy, ['']))) self.assertFalse(self.rules_checker.check_property_rules( 'x_none_read', 'delete', create_context(self.policy, ['']))) def test_check_property_rules_update_none(self): self.rules_checker = property_utils.PropertyRules() self.assertTrue(self.rules_checker.check_property_rules( 'x_none_update', 'create', create_context(self.policy, ['admin', 'member']))) self.assertTrue(self.rules_checker.check_property_rules( 'x_none_update', 'read', create_context(self.policy, ['admin', 'member']))) self.assertFalse(self.rules_checker.check_property_rules( 'x_none_update', 'update', create_context(self.policy, ['']))) self.assertTrue(self.rules_checker.check_property_rules( 'x_none_update', 'delete', create_context(self.policy, ['admin', 'member']))) def test_check_property_rules_delete_none(self): self.rules_checker = property_utils.PropertyRules() self.assertTrue(self.rules_checker.check_property_rules( 'x_none_delete', 'create', create_context(self.policy, ['admin', 'member']))) self.assertTrue(self.rules_checker.check_property_rules( 'x_none_delete', 'read', create_context(self.policy, ['admin', 'member']))) self.assertTrue(self.rules_checker.check_property_rules( 'x_none_delete', 'update', create_context(self.policy, ['admin', 'member']))) self.assertFalse(self.rules_checker.check_property_rules( 'x_none_delete', 'delete', create_context(self.policy, ['']))) def test_check_return_first_match(self): self.rules_checker = property_utils.PropertyRules() self.assertFalse(self.rules_checker.check_property_rules( 'x_foo_matcher', 'create', create_context(self.policy, ['']))) self.assertFalse(self.rules_checker.check_property_rules( 'x_foo_matcher', 'read', create_context(self.policy, ['']))) self.assertFalse(self.rules_checker.check_property_rules( 'x_foo_matcher', 'update', create_context(self.policy, ['']))) self.assertFalse(self.rules_checker.check_property_rules( 'x_foo_matcher', 'delete', create_context(self.policy, ['']))) glance-2014.1/glance/tests/unit/common/test_utils.py0000664000175400017540000002050612323736226023614 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import os import tempfile import uuid import six import webob from glance.common import exception from glance.common import utils from glance.tests import utils as test_utils class TestUtils(test_utils.BaseTestCase): """Test routines in glance.utils""" def test_cooperative_reader(self): """Ensure cooperative reader class accesses all bytes of file""" BYTES = 1024 bytes_read = 0 with tempfile.TemporaryFile('w+') as tmp_fd: tmp_fd.write('*' * BYTES) tmp_fd.seek(0) for chunk in utils.CooperativeReader(tmp_fd): bytes_read += len(chunk) self.assertEqual(bytes_read, BYTES) bytes_read = 0 with tempfile.TemporaryFile('w+') as tmp_fd: tmp_fd.write('*' * BYTES) tmp_fd.seek(0) reader = utils.CooperativeReader(tmp_fd) byte = reader.read(1) while len(byte) != 0: bytes_read += 1 byte = reader.read(1) self.assertEqual(bytes_read, BYTES) def test_cooperative_reader_of_iterator(self): """Ensure cooperative reader supports iterator backends too""" reader = utils.CooperativeReader([l * 3 for l in 'abcdefgh']) chunks = [] while True: chunks.append(reader.read(3)) if chunks[-1] == '': break meat = ''.join(chunks) self.assertEqual(meat, 'aaabbbcccdddeeefffggghhh') def test_cooperative_reader_of_iterator_stop_iteration_err(self): """Ensure cooperative reader supports iterator backends too""" reader = utils.CooperativeReader([l * 3 for l in '']) chunks = [] while True: chunks.append(reader.read(3)) if chunks[-1] == '': break meat = ''.join(chunks) self.assertEqual(meat, '') def test_limiting_reader(self): """Ensure limiting reader class accesses all bytes of file""" BYTES = 1024 bytes_read = 0 data = six.StringIO("*" * BYTES) for chunk in utils.LimitingReader(data, BYTES): bytes_read += len(chunk) self.assertEqual(bytes_read, BYTES) bytes_read = 0 data = six.StringIO("*" * BYTES) reader = utils.LimitingReader(data, BYTES) byte = reader.read(1) while len(byte) != 0: bytes_read += 1 byte = reader.read(1) self.assertEqual(bytes_read, BYTES) def test_limiting_reader_fails(self): """Ensure limiting reader class throws exceptions if limit exceeded""" BYTES = 1024 def _consume_all_iter(): bytes_read = 0 data = six.StringIO("*" * BYTES) for chunk in utils.LimitingReader(data, BYTES - 1): bytes_read += len(chunk) self.assertRaises(exception.ImageSizeLimitExceeded, _consume_all_iter) def _consume_all_read(): bytes_read = 0 data = six.StringIO("*" * BYTES) reader = utils.LimitingReader(data, BYTES - 1) byte = reader.read(1) while len(byte) != 0: bytes_read += 1 byte = reader.read(1) self.assertRaises(exception.ImageSizeLimitExceeded, _consume_all_read) def test_get_meta_from_headers(self): resp = webob.Response() resp.headers = {"x-image-meta-name": 'test'} result = utils.get_image_meta_from_headers(resp) self.assertEqual({'name': 'test', 'properties': {}}, result) def test_get_meta_from_headers_bad_headers(self): resp = webob.Response() resp.headers = {"x-image-meta-bad": 'test'} self.assertRaises(webob.exc.HTTPBadRequest, utils.get_image_meta_from_headers, resp) resp.headers = {"x-image-meta-": 'test'} self.assertRaises(webob.exc.HTTPBadRequest, utils.get_image_meta_from_headers, resp) resp.headers = {"x-image-meta-*": 'test'} self.assertRaises(webob.exc.HTTPBadRequest, utils.get_image_meta_from_headers, resp) def test_add_features_to_http_headers(self): features_test1 = {'x-image-meta-size': 'test'} url = ("http://glance.example.com/v1/" "images/71c675ab-d94f-49cd-a114-e12490b328d9") headers = {"x-image-meta-uri": url} self.assertRaises(exception.UnsupportedHeaderFeature, utils.add_features_to_http_headers, features_test1, headers) def test_image_meta(self): image_meta = {'x-image-meta-size': 'test'} image_meta_properties = {'properties': {'test': "test"}} actual = utils.image_meta_to_http_headers(image_meta) actual_test2 = utils.image_meta_to_http_headers( image_meta_properties) self.assertEqual({'x-image-meta-x-image-meta-size': u'test'}, actual) self.assertEqual({'x-image-meta-property-test': u'test'}, actual_test2) def test_create_pretty_table(self): class MyPrettyTable(utils.PrettyTable): def __init__(self): self.columns = [] # Test add column my_pretty_table = MyPrettyTable() my_pretty_table.add_column(1, label='test') # Test make header test_res = my_pretty_table.make_header() self.assertEqual('t\n-', test_res) # Test make row result = my_pretty_table.make_row('t') self.assertEqual("t", result) result = my_pretty_table._clip_and_justify( data='test', width=4, just=1) self.assertEqual("test", result) def test_mutating(self): class FakeContext(): def __init__(self): self.read_only = False class Fake(): def __init__(self): self.context = FakeContext() def fake_function(req, context): return 'test passed' req = webob.Request.blank('/some_request') result = utils.mutating(fake_function) self.assertEqual("test passed", result(req, Fake())) def test_validate_key_cert_key(self): var_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../', 'var')) keyfile = os.path.join(var_dir, 'privatekey.key') certfile = os.path.join(var_dir, 'certificate.crt') utils.validate_key_cert(keyfile, certfile) def test_validate_key_cert_no_private_key(self): with tempfile.NamedTemporaryFile('w+') as tmpf: self.assertRaises(RuntimeError, utils.validate_key_cert, "/not/a/file", tmpf.name) def test_validate_key_cert_cert_cant_read(self): with tempfile.NamedTemporaryFile('w+') as keyf: with tempfile.NamedTemporaryFile('w+') as certf: os.chmod(certf.name, 0) self.assertRaises(RuntimeError, utils.validate_key_cert, keyf.name, certf.name) def test_validate_key_cert_key_cant_read(self): with tempfile.NamedTemporaryFile('w+') as keyf: with tempfile.NamedTemporaryFile('w+') as keyf: os.chmod(keyf.name, 0) self.assertRaises(RuntimeError, utils.validate_key_cert, keyf.name, keyf.name) class UUIDTestCase(test_utils.BaseTestCase): def test_is_uuid_like(self): self.assertTrue(utils.is_uuid_like(str(uuid.uuid4()))) def test_id_is_uuid_like(self): self.assertFalse(utils.is_uuid_like(1234567)) def test_name_is_uuid_like(self): self.assertFalse(utils.is_uuid_like('zhongyueluo')) glance-2014.1/glance/tests/unit/common/__init__.py0000664000175400017540000000000012323736226023137 0ustar jenkinsjenkins00000000000000glance-2014.1/glance/tests/unit/common/test_rpc.py0000664000175400017540000002773012323736226023246 0ustar jenkinsjenkins00000000000000# -*- coding: utf-8 -*- # Copyright 2013 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. import datetime import mox from oslo.config import cfg import routes import webob from glance.common import exception from glance.common import rpc from glance.common import wsgi from glance.openstack.common import jsonutils from glance.tests.unit import base from glance.tests import utils as test_utils CONF = cfg.CONF class FakeResource(object): """ Fake resource defining some methods that will be called later by the api. """ def get_images(self, context, keyword=None): return keyword def count_images(self, context, images): return len(images) def get_all_images(self, context): return False def raise_value_error(self, context): raise ValueError("Yep, Just like that!") def raise_weird_error(self, context): class WeirdError(Exception): pass raise WeirdError("Weirdness") def create_api(): deserializer = rpc.RPCJSONDeserializer() serializer = rpc.RPCJSONSerializer() controller = rpc.Controller() controller.register(FakeResource()) res = wsgi.Resource(controller, deserializer, serializer) mapper = routes.Mapper() mapper.connect("/rpc", controller=res, conditions=dict(method=["POST"]), action="__call__") return test_utils.FakeAuthMiddleware(wsgi.Router(mapper), is_admin=True) class TestRPCController(base.IsolatedUnitTest): def setUp(self): super(TestRPCController, self).setUp() self.res = FakeResource() self.controller = rpc.Controller() self.controller.register(self.res) # Mock self.mocker = mox.Mox() def test_register(self): res = FakeResource() controller = rpc.Controller() controller.register(res) self.assertIn("get_images", controller._registered) self.assertIn("get_all_images", controller._registered) def test_reigster_filtered(self): res = FakeResource() controller = rpc.Controller() controller.register(res, filtered=["get_all_images"]) self.assertIn("get_all_images", controller._registered) def test_reigster_excluded(self): res = FakeResource() controller = rpc.Controller() controller.register(res, excluded=["get_all_images"]) self.assertIn("get_images", controller._registered) def test_reigster_refiner(self): res = FakeResource() controller = rpc.Controller() # Not callable self.assertRaises(AssertionError, controller.register, res, refiner="get_all_images") # Filter returns False controller.register(res, refiner=lambda x: False) self.assertNotIn("get_images", controller._registered) self.assertNotIn("get_images", controller._registered) # Filter returns True controller.register(res, refiner=lambda x: True) self.assertIn("get_images", controller._registered) self.assertIn("get_images", controller._registered) def test_request(self): api = create_api() req = webob.Request.blank('/rpc') req.method = 'POST' req.body = jsonutils.dumps([ { "command": "get_images", "kwargs": {"keyword": 1} } ]) res = req.get_response(api) returned = jsonutils.loads(res.body) self.assertIsInstance(returned, list) self.assertEqual(returned[0], 1) def test_request_exc(self): api = create_api() req = webob.Request.blank('/rpc') req.method = 'POST' req.body = jsonutils.dumps([ { "command": "get_all_images", "kwargs": {"keyword": 1} } ]) # Sending non-accepted keyword # to get_all_images method res = req.get_response(api) returned = jsonutils.loads(res.body) self.assertIn("_error", returned[0]) def test_rpc_errors(self): api = create_api() req = webob.Request.blank('/rpc') req.method = 'POST' req.content_type = 'application/json' # Body is not a list, it should fail req.body = jsonutils.dumps({}) res = req.get_response(api) self.assertEqual(res.status_int, 400) # cmd is not dict, it should fail. req.body = jsonutils.dumps([None]) res = req.get_response(api) self.assertEqual(res.status_int, 400) # No command key, it should fail. req.body = jsonutils.dumps([{}]) res = req.get_response(api) self.assertEqual(res.status_int, 400) # kwargs not dict, it should fail. req.body = jsonutils.dumps([{"command": "test", "kwargs": 200}]) res = req.get_response(api) self.assertEqual(res.status_int, 400) # Command does not exist, it should fail. req.body = jsonutils.dumps([{"command": "test"}]) res = req.get_response(api) self.assertEqual(res.status_int, 404) def test_rpc_exception_propagation(self): api = create_api() req = webob.Request.blank('/rpc') req.method = 'POST' req.content_type = 'application/json' req.body = jsonutils.dumps([{"command": "raise_value_error"}]) res = req.get_response(api) self.assertEqual(res.status_int, 200) returned = jsonutils.loads(res.body)[0] self.assertEqual(returned['_error']['cls'], 'exceptions.ValueError') req.body = jsonutils.dumps([{"command": "raise_weird_error"}]) res = req.get_response(api) self.assertEqual(res.status_int, 200) returned = jsonutils.loads(res.body)[0] self.assertEqual(returned['_error']['cls'], 'glance.common.exception.RPCError') class TestRPCClient(base.IsolatedUnitTest): def setUp(self): super(TestRPCClient, self).setUp() self.api = create_api() self.client = rpc.RPCClient(host="http://127.0.0.1:9191") self.client._do_request = self.fake_request def fake_request(self, method, url, body, headers): req = webob.Request.blank(url.path) req.body = body req.method = method webob_res = req.get_response(self.api) return test_utils.FakeHTTPResponse(status=webob_res.status_int, headers=webob_res.headers, data=webob_res.body) def test_method_proxy(self): proxy = self.client.some_method self.assertIn("method_proxy", str(proxy)) def test_bulk_request(self): commands = [{"command": "get_images", 'kwargs': {'keyword': True}}, {"command": "get_all_images"}] res = self.client.bulk_request(commands) self.assertEqual(len(res), 2) self.assertTrue(res[0]) self.assertFalse(res[1]) def test_exception_raise(self): try: self.client.raise_value_error() self.fail("Exception not raised") except ValueError as exc: self.assertEqual(str(exc), "Yep, Just like that!") def test_rpc_exception(self): try: self.client.raise_weird_error() self.fail("Exception not raised") except exception.RPCError: pass def test_non_str_or_dict_response(self): rst = self.client.count_images(images=[1, 2, 3, 4]) self.assertEqual(rst, 4) self.assertIsInstance(rst, int) class TestRPCJSONSerializer(test_utils.BaseTestCase): def test_to_json(self): fixture = {"key": "value"} expected = '{"key": "value"}' actual = rpc.RPCJSONSerializer().to_json(fixture) self.assertEqual(actual, expected) def test_to_json_with_date_format_value(self): fixture = {"date": datetime.datetime(1900, 3, 8, 2)} expected = ('{"date": {"_value": "1900-03-08T02:00:00.000000", ' '"_type": "datetime"}}') actual = rpc.RPCJSONSerializer().to_json(fixture) self.assertEqual(actual, expected) def test_to_json_with_more_deep_format(self): fixture = {"is_public": True, "name": [{"name1": "test"}]} expected = '{"is_public": true, "name": [{"name1": "test"}]}' actual = rpc.RPCJSONSerializer().to_json(fixture) self.assertEqual(actual, expected) def test_default(self): fixture = {"key": "value"} response = webob.Response() rpc.RPCJSONSerializer().default(response, fixture) self.assertEqual(response.status_int, 200) content_types = filter(lambda h: h[0] == 'Content-Type', response.headerlist) self.assertEqual(len(content_types), 1) self.assertEqual(response.content_type, 'application/json') self.assertEqual(response.body, '{"key": "value"}') class TestRPCJSONDeserializer(test_utils.BaseTestCase): def test_has_body_no_content_length(self): request = wsgi.Request.blank('/') request.method = 'POST' request.body = 'asdf' request.headers.pop('Content-Length') self.assertFalse(rpc.RPCJSONDeserializer().has_body(request)) def test_has_body_zero_content_length(self): request = wsgi.Request.blank('/') request.method = 'POST' request.body = 'asdf' request.headers['Content-Length'] = 0 self.assertFalse(rpc.RPCJSONDeserializer().has_body(request)) def test_has_body_has_content_length(self): request = wsgi.Request.blank('/') request.method = 'POST' request.body = 'asdf' self.assertTrue('Content-Length' in request.headers) self.assertTrue(rpc.RPCJSONDeserializer().has_body(request)) def test_no_body_no_content_length(self): request = wsgi.Request.blank('/') self.assertFalse(rpc.RPCJSONDeserializer().has_body(request)) def test_from_json(self): fixture = '{"key": "value"}' expected = {"key": "value"} actual = rpc.RPCJSONDeserializer().from_json(fixture) self.assertEqual(actual, expected) def test_from_json_malformed(self): fixture = 'kjasdklfjsklajf' self.assertRaises(webob.exc.HTTPBadRequest, rpc.RPCJSONDeserializer().from_json, fixture) def test_default_no_body(self): request = wsgi.Request.blank('/') actual = rpc.RPCJSONDeserializer().default(request) expected = {} self.assertEqual(actual, expected) def test_default_with_body(self): request = wsgi.Request.blank('/') request.method = 'POST' request.body = '{"key": "value"}' actual = rpc.RPCJSONDeserializer().default(request) expected = {"body": {"key": "value"}} self.assertEqual(actual, expected) def test_has_body_has_transfer_encoding(self): request = wsgi.Request.blank('/') request.method = 'POST' request.body = 'fake_body' request.headers['transfer-encoding'] = 0 self.assertTrue('transfer-encoding' in request.headers) self.assertTrue(rpc.RPCJSONDeserializer().has_body(request)) def test_to_json_with_date_format_value(self): fixture = ('{"date": {"_value": "1900-03-08T02:00:00.000000",' '"_type": "datetime"}}') expected = {"date": datetime.datetime(1900, 3, 8, 2)} actual = rpc.RPCJSONDeserializer().from_json(fixture) self.assertEqual(actual, expected) glance-2014.1/glance/tests/unit/test_notifier.py0000664000175400017540000004733712323736230023011 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation # Copyright 2013 IBM Corp. # 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 datetime import mock import webob from glance.common import exception import glance.context from glance import domain from glance import notifier from glance.openstack.common import timeutils import glance.tests.unit.utils as unit_test_utils from glance.tests import utils DATETIME = datetime.datetime(2012, 5, 16, 15, 27, 36, 325355) UUID1 = 'c80a1a6c-bd1f-41c5-90ee-81afedb1d58d' USER1 = '54492ba0-f4df-4e4e-be62-27f4d76b29cf' TENANT1 = '6838eb7b-6ded-434a-882c-b344c77fe8df' TENANT2 = '2c014f32-55eb-467d-8fcb-4bd706012f81' class ImageStub(glance.domain.Image): def get_data(self): return ['01234', '56789'] def set_data(self, data, size=None): for chunk in data: pass class ImageRepoStub(object): def remove(self, *args, **kwargs): return 'image_from_get' def save(self, *args, **kwargs): return 'image_from_save' def add(self, *args, **kwargs): return 'image_from_add' def get(self, *args, **kwargs): return 'image_from_get' def list(self, *args, **kwargs): return ['images_from_list'] class TaskStub(glance.domain.Task): def run(self, executor): pass def succeed(self, result): pass def fail(self, message): pass class TaskRepoStub(object): def remove(self, *args, **kwargs): return 'task_from_remove' def save(self, *args, **kwargs): return 'task_from_save' def add(self, *args, **kwargs): return 'task_from_add' def get(self, *args, **kwargs): return 'task_from_get' def list(self, *args, **kwargs): return ['tasks_from_list'] class TestNotifier(utils.BaseTestCase): def test_load_rabbit(self): nfier = notifier.Notifier('rabbit') self.assertIsNotNone(nfier._transport) def test_load_qpid(self): nfier = notifier.Notifier('qpid') self.assertIsNotNone(nfier._transport) self.assertEqual(str(nfier._transport._driver._url), 'qpid:///') def test_notifier_strategy(self): self.config(notifier_strategy='qpid') nfier = notifier.Notifier() self.assertIsNotNone(nfier._transport) self.assertEqual(str(nfier._transport._driver._url), 'qpid:///') def test_transport_url(self): transport_url = "qpid://superhost:5672/" self.config(transport_url=transport_url) notify = notifier.Notifier() self.assertEqual(str(notify._transport._driver._url), transport_url) def test_notification_driver_option(self): self.config(rpc_backend='qpid') self.config(notification_driver='messaging') self.config(notifier_strategy='rabbit') notify = notifier.Notifier() self.assertEqual(str(notify._transport._driver._url), 'rabbit:///') self.config(notifier_strategy='default') notify = notifier.Notifier() self.assertEqual(str(notify._transport._driver._url), 'qpid:///') class TestImageNotifications(utils.BaseTestCase): """Test Image Notifications work""" def setUp(self): super(TestImageNotifications, self).setUp() self.image = ImageStub( image_id=UUID1, name='image-1', status='active', size=1024, created_at=DATETIME, updated_at=DATETIME, owner=TENANT1, visibility='public', container_format='ami', tags=['one', 'two'], disk_format='ami', min_ram=128, min_disk=10, checksum='ca425b88f047ce8ec45ee90e813ada91', locations=['http://127.0.0.1']) self.context = glance.context.RequestContext(tenant=TENANT2, user=USER1) self.image_repo_stub = ImageRepoStub() self.notifier = unit_test_utils.FakeNotifier() self.image_repo_proxy = glance.notifier.ImageRepoProxy( self.image_repo_stub, self.context, self.notifier) self.image_proxy = glance.notifier.ImageProxy( self.image, self.context, self.notifier) def test_image_save_notification(self): self.image_repo_proxy.save(self.image_proxy) output_logs = self.notifier.get_logs() self.assertEqual(len(output_logs), 1) output_log = output_logs[0] self.assertEqual(output_log['notification_type'], 'INFO') self.assertEqual(output_log['event_type'], 'image.update') self.assertEqual(output_log['payload']['id'], self.image.image_id) if 'location' in output_log['payload']: self.fail('Notification contained location field.') def test_image_add_notification(self): self.image_repo_proxy.add(self.image_proxy) output_logs = self.notifier.get_logs() self.assertEqual(len(output_logs), 1) output_log = output_logs[0] self.assertEqual(output_log['notification_type'], 'INFO') self.assertEqual(output_log['event_type'], 'image.create') self.assertEqual(output_log['payload']['id'], self.image.image_id) if 'location' in output_log['payload']: self.fail('Notification contained location field.') def test_image_delete_notification(self): self.image_repo_proxy.remove(self.image_proxy) output_logs = self.notifier.get_logs() self.assertEqual(len(output_logs), 1) output_log = output_logs[0] self.assertEqual(output_log['notification_type'], 'INFO') self.assertEqual(output_log['event_type'], 'image.delete') self.assertEqual(output_log['payload']['id'], self.image.image_id) self.assertTrue(output_log['payload']['deleted']) if 'location' in output_log['payload']: self.fail('Notification contained location field.') def test_image_get(self): image = self.image_repo_proxy.get(UUID1) self.assertIsInstance(image, glance.notifier.ImageProxy) self.assertEqual(image.image, 'image_from_get') def test_image_list(self): images = self.image_repo_proxy.list() self.assertIsInstance(images[0], glance.notifier.ImageProxy) self.assertEqual(images[0].image, 'images_from_list') def test_image_get_data_notification(self): self.image_proxy.size = 10 data = ''.join(self.image_proxy.get_data()) self.assertEqual(data, '0123456789') output_logs = self.notifier.get_logs() self.assertEqual(len(output_logs), 1) output_log = output_logs[0] self.assertEqual(output_log['notification_type'], 'INFO') self.assertEqual(output_log['event_type'], 'image.send') self.assertEqual(output_log['payload']['image_id'], self.image.image_id) self.assertEqual(output_log['payload']['receiver_tenant_id'], TENANT2) self.assertEqual(output_log['payload']['receiver_user_id'], USER1) self.assertEqual(output_log['payload']['bytes_sent'], 10) self.assertEqual(output_log['payload']['owner_id'], TENANT1) def test_image_get_data_size_mismatch(self): self.image_proxy.size = 11 list(self.image_proxy.get_data()) output_logs = self.notifier.get_logs() self.assertEqual(len(output_logs), 1) output_log = output_logs[0] self.assertEqual(output_log['notification_type'], 'ERROR') self.assertEqual(output_log['event_type'], 'image.send') self.assertEqual(output_log['payload']['image_id'], self.image.image_id) def test_image_set_data_prepare_notification(self): insurance = {'called': False} def data_iterator(): output_logs = self.notifier.get_logs() self.assertEqual(len(output_logs), 1) output_log = output_logs[0] self.assertEqual(output_log['notification_type'], 'INFO') self.assertEqual(output_log['event_type'], 'image.prepare') self.assertEqual(output_log['payload']['id'], self.image.image_id) yield 'abcd' yield 'efgh' insurance['called'] = True self.image_proxy.set_data(data_iterator(), 8) self.assertTrue(insurance['called']) def test_image_set_data_upload_and_activate_notification(self): def data_iterator(): self.notifier.log = [] yield 'abcde' yield 'fghij' self.image_proxy.set_data(data_iterator(), 10) output_logs = self.notifier.get_logs() self.assertEqual(len(output_logs), 2) output_log = output_logs[0] self.assertEqual(output_log['notification_type'], 'INFO') self.assertEqual(output_log['event_type'], 'image.upload') self.assertEqual(output_log['payload']['id'], self.image.image_id) output_log = output_logs[1] self.assertEqual(output_log['notification_type'], 'INFO') self.assertEqual(output_log['event_type'], 'image.activate') self.assertEqual(output_log['payload']['id'], self.image.image_id) def test_image_set_data_storage_full(self): def data_iterator(): self.notifier.log = [] yield 'abcde' raise exception.StorageFull('Modern Major General') self.assertRaises(webob.exc.HTTPRequestEntityTooLarge, self.image_proxy.set_data, data_iterator(), 10) output_logs = self.notifier.get_logs() self.assertEqual(len(output_logs), 1) output_log = output_logs[0] self.assertEqual(output_log['notification_type'], 'ERROR') self.assertEqual(output_log['event_type'], 'image.upload') self.assertTrue('Modern Major General' in output_log['payload']) def test_image_set_data_value_error(self): def data_iterator(): self.notifier.log = [] yield 'abcde' raise ValueError('value wrong') self.assertRaises(webob.exc.HTTPBadRequest, self.image_proxy.set_data, data_iterator(), 10) output_logs = self.notifier.get_logs() self.assertEqual(len(output_logs), 1) output_log = output_logs[0] self.assertEqual(output_log['notification_type'], 'ERROR') self.assertEqual(output_log['event_type'], 'image.upload') self.assertTrue('value wrong' in output_log['payload']) def test_image_set_data_duplicate(self): def data_iterator(): self.notifier.log = [] yield 'abcde' raise exception.Duplicate('Cant have duplicates') self.assertRaises(webob.exc.HTTPConflict, self.image_proxy.set_data, data_iterator(), 10) output_logs = self.notifier.get_logs() self.assertEqual(len(output_logs), 1) output_log = output_logs[0] self.assertEqual(output_log['notification_type'], 'ERROR') self.assertEqual(output_log['event_type'], 'image.upload') self.assertTrue('Cant have duplicates' in output_log['payload']) def test_image_set_data_storage_write_denied(self): def data_iterator(): self.notifier.log = [] yield 'abcde' raise exception.StorageWriteDenied('The Very Model') self.assertRaises(webob.exc.HTTPServiceUnavailable, self.image_proxy.set_data, data_iterator(), 10) output_logs = self.notifier.get_logs() self.assertEqual(len(output_logs), 1) output_log = output_logs[0] self.assertEqual(output_log['notification_type'], 'ERROR') self.assertEqual(output_log['event_type'], 'image.upload') self.assertTrue('The Very Model' in output_log['payload']) def test_image_set_data_forbidden(self): def data_iterator(): self.notifier.log = [] yield 'abcde' raise exception.Forbidden('Not allowed') self.assertRaises(webob.exc.HTTPForbidden, self.image_proxy.set_data, data_iterator(), 10) output_logs = self.notifier.get_logs() self.assertEqual(len(output_logs), 1) output_log = output_logs[0] self.assertEqual(output_log['notification_type'], 'ERROR') self.assertEqual(output_log['event_type'], 'image.upload') self.assertTrue('Not allowed' in output_log['payload']) def test_image_set_data_not_found(self): def data_iterator(): self.notifier.log = [] yield 'abcde' raise exception.NotFound('Not found') self.assertRaises(webob.exc.HTTPNotFound, self.image_proxy.set_data, data_iterator(), 10) output_logs = self.notifier.get_logs() self.assertEqual(len(output_logs), 1) output_log = output_logs[0] self.assertEqual(output_log['notification_type'], 'ERROR') self.assertEqual(output_log['event_type'], 'image.upload') self.assertTrue('Not found' in output_log['payload']) def test_image_set_data_HTTP_error(self): def data_iterator(): self.notifier.log = [] yield 'abcde' raise webob.exc.HTTPError('Http issue') self.assertRaises(webob.exc.HTTPError, self.image_proxy.set_data, data_iterator(), 10) output_logs = self.notifier.get_logs() self.assertEqual(len(output_logs), 1) output_log = output_logs[0] self.assertEqual(output_log['notification_type'], 'ERROR') self.assertEqual(output_log['event_type'], 'image.upload') self.assertTrue('Http issue' in output_log['payload']) def test_image_set_data_error(self): def data_iterator(): self.notifier.log = [] yield 'abcde' raise exception.GlanceException('Failed') self.assertRaises(exception.GlanceException, self.image_proxy.set_data, data_iterator(), 10) output_logs = self.notifier.get_logs() self.assertEqual(len(output_logs), 1) output_log = output_logs[0] self.assertEqual(output_log['notification_type'], 'ERROR') self.assertEqual(output_log['event_type'], 'image.upload') self.assertTrue('Failed' in output_log['payload']) class TestTaskNotifications(utils.BaseTestCase): """Test Task Notifications work""" def setUp(self): super(TestTaskNotifications, self).setUp() self.task = TaskStub( task_id='aaa', task_type='import', status='pending', owner=TENANT2, expires_at=None, created_at=DATETIME, updated_at=DATETIME ) self.task_details = domain.TaskDetails(task_id=self.task.task_id, task_input={"loc": "fake"}, result='', message='') self.context = glance.context.RequestContext( tenant=TENANT2, user=USER1 ) self.task_repo_stub = TaskRepoStub() self.notifier = unit_test_utils.FakeNotifier() self.task_repo_proxy = glance.notifier.TaskRepoProxy( self.task_repo_stub, self.context, self.notifier ) self.task_proxy = glance.notifier.TaskProxy( self.task, self.context, self.notifier ) self.task_details_proxy = notifier.TaskDetailsProxy(self.task_details, self.context, self.notifier) self.patcher = mock.patch.object(timeutils, 'utcnow') mock_utcnow = self.patcher.start() mock_utcnow.return_value = datetime.datetime.utcnow() def tearDown(self): super(TestTaskNotifications, self).tearDown() self.patcher.stop() def test_task_create_notification(self): self.task_repo_proxy.add(self.task_proxy, self.task_details_proxy) output_logs = self.notifier.get_logs() self.assertEqual(len(output_logs), 1) output_log = output_logs[0] self.assertEqual(output_log['notification_type'], 'INFO') self.assertEqual(output_log['event_type'], 'task.create') self.assertEqual(output_log['payload']['id'], self.task.task_id) self.assertEqual( output_log['payload']['updated_at'], timeutils.isotime(self.task.updated_at) ) self.assertEqual( output_log['payload']['created_at'], timeutils.isotime(self.task.created_at) ) if 'location' in output_log['payload']: self.fail('Notification contained location field.') def test_task_delete_notification(self): now = timeutils.isotime() self.task_repo_proxy.remove(self.task_proxy) output_logs = self.notifier.get_logs() self.assertEqual(len(output_logs), 1) output_log = output_logs[0] self.assertEqual(output_log['notification_type'], 'INFO') self.assertEqual(output_log['event_type'], 'task.delete') self.assertEqual(output_log['payload']['id'], self.task.task_id) self.assertEqual( output_log['payload']['updated_at'], timeutils.isotime(self.task.updated_at) ) self.assertEqual( output_log['payload']['created_at'], timeutils.isotime(self.task.created_at) ) self.assertEqual( output_log['payload']['deleted_at'], now ) if 'location' in output_log['payload']: self.fail('Notification contained location field.') def test_task_run_notification(self): self.task_proxy.run(executor=None) output_logs = self.notifier.get_logs() self.assertEqual(len(output_logs), 1) output_log = output_logs[0] self.assertEqual(output_log['notification_type'], 'INFO') self.assertEqual(output_log['event_type'], 'task.run') self.assertEqual(output_log['payload']['id'], self.task.task_id) def test_task_processing_notification(self): self.task_proxy.begin_processing() output_logs = self.notifier.get_logs() self.assertEqual(len(output_logs), 1) output_log = output_logs[0] self.assertEqual(output_log['notification_type'], 'INFO') self.assertEqual(output_log['event_type'], 'task.processing') self.assertEqual(output_log['payload']['id'], self.task.task_id) def test_task_success_notification(self): self.task_proxy.begin_processing() self.task_proxy.succeed(result=None) output_logs = self.notifier.get_logs() self.assertEqual(len(output_logs), 2) output_log = output_logs[1] self.assertEqual(output_log['notification_type'], 'INFO') self.assertEqual(output_log['event_type'], 'task.success') self.assertEqual(output_log['payload']['id'], self.task.task_id) def test_task_failure_notification(self): self.task_proxy.fail(message=None) output_logs = self.notifier.get_logs() self.assertEqual(len(output_logs), 1) output_log = output_logs[0] self.assertEqual(output_log['notification_type'], 'INFO') self.assertEqual(output_log['event_type'], 'task.failure') self.assertEqual(output_log['payload']['id'], self.task.task_id) glance-2014.1/glance/tests/unit/test_store_image.py0000664000175400017540000010625012323736226023463 0ustar jenkinsjenkins00000000000000# Copyright 2012 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import mox from glance.common import exception import glance.store from glance.tests.unit import utils as unit_test_utils from glance.tests import utils BASE_URI = 'http://storeurl.com/container' UUID1 = 'c80a1a6c-bd1f-41c5-90ee-81afedb1d58d' UUID2 = '971ec09a-8067-4bc8-a91f-ae3557f1c4c7' USER1 = '54492ba0-f4df-4e4e-be62-27f4d76b29cf' TENANT1 = '6838eb7b-6ded-434a-882c-b344c77fe8df' TENANT2 = '2c014f32-55eb-467d-8fcb-4bd706012f81' TENANT3 = '228c6da5-29cd-4d67-9457-ed632e083fc0' class ImageRepoStub(object): def add(self, image): return image def save(self, image): return image class ImageStub(object): def __init__(self, image_id, status=None, locations=None, visibility=None): self.image_id = image_id self.status = status self.locations = locations or [] self.visibility = visibility self.size = 1 def delete(self): self.status = 'deleted' def get_member_repo(self): return FakeMemberRepo(self, [TENANT1, TENANT2]) class ImageFactoryStub(object): def new_image(self, image_id=None, name=None, visibility='private', min_disk=0, min_ram=0, protected=False, owner=None, disk_format=None, container_format=None, extra_properties=None, tags=None, **other_args): return ImageStub(image_id, visibility=visibility, **other_args) class FakeMemberRepo(object): def __init__(self, image, tenants=None): self.image = image self.factory = glance.domain.ImageMemberFactory() self.tenants = tenants or [] def list(self, *args, **kwargs): return [self.factory.new_image_member(self.image, tenant) for tenant in self.tenants] def add(self, member): self.tenants.append(member.member_id) def remove(self, member): self.tenants.remove(member.member_id) class TestStoreImage(utils.BaseTestCase): def setUp(self): locations = [{'url': '%s/%s' % (BASE_URI, UUID1), 'metadata': {}}] self.image_stub = ImageStub(UUID1, 'active', locations) self.store_api = unit_test_utils.FakeStoreAPI() super(TestStoreImage, self).setUp() def test_image_delete(self): image = glance.store.ImageProxy(self.image_stub, {}, self.store_api) location = image.locations[0] self.assertEqual(image.status, 'active') self.store_api.get_from_backend({}, location['url']) image.delete() self.assertEqual(image.status, 'deleted') self.assertRaises(exception.NotFound, self.store_api.get_from_backend, {}, location['url']) def test_image_get_data(self): image = glance.store.ImageProxy(self.image_stub, {}, self.store_api) self.assertEqual(image.get_data(), 'XXX') def test_image_get_data_from_second_location(self): def fake_get_from_backend(self, context, location): if UUID1 in location: raise Exception('not allow download from %s' % location) else: return self.data[location] image1 = glance.store.ImageProxy(self.image_stub, {}, self.store_api) self.assertEqual(image1.get_data(), 'XXX') # Multiple location support context = glance.context.RequestContext(user=USER1) (image2, image_stub2) = self._add_image(context, UUID2, 'ZZZ', 3) location_data = image2.locations[0] image1.locations.append(location_data) self.assertEqual(len(image1.locations), 2) self.assertEqual(location_data['url'], UUID2) self.stubs.Set(unit_test_utils.FakeStoreAPI, 'get_from_backend', fake_get_from_backend) self.assertEqual(image1.get_data().fd, 'ZZZ') image1.locations.pop(0) self.assertEqual(len(image1.locations), 1) image2.delete() def test_image_set_data(self): context = glance.context.RequestContext(user=USER1) image_stub = ImageStub(UUID2, status='queued', locations=[]) image = glance.store.ImageProxy(image_stub, context, self.store_api) image.set_data('YYYY', 4) self.assertEqual(image.size, 4) #NOTE(markwash): FakeStore returns image_id for location self.assertEqual(image.locations[0]['url'], UUID2) self.assertEqual(image.checksum, 'Z') self.assertEqual(image.status, 'active') def test_image_set_data_location_metadata(self): context = glance.context.RequestContext(user=USER1) image_stub = ImageStub(UUID2, status='queued', locations=[]) loc_meta = {'key': 'value5032'} store_api = unit_test_utils.FakeStoreAPI(store_metadata=loc_meta) image = glance.store.ImageProxy(image_stub, context, store_api) image.set_data('YYYY', 4) self.assertEqual(image.size, 4) location_data = image.locations[0] self.assertEqual(location_data['url'], UUID2) self.assertEqual(location_data['metadata'], loc_meta) self.assertEqual(image.checksum, 'Z') self.assertEqual(image.status, 'active') image.delete() self.assertEqual(image.status, 'deleted') self.assertRaises(exception.NotFound, self.store_api.get_from_backend, {}, image.locations[0]['url']) def test_image_set_data_unknown_size(self): context = glance.context.RequestContext(user=USER1) image_stub = ImageStub(UUID2, status='queued', locations=[]) image = glance.store.ImageProxy(image_stub, context, self.store_api) image.set_data('YYYY', None) self.assertEqual(image.size, 4) #NOTE(markwash): FakeStore returns image_id for location self.assertEqual(image.locations[0]['url'], UUID2) self.assertEqual(image.checksum, 'Z') self.assertEqual(image.status, 'active') image.delete() self.assertEqual(image.status, 'deleted') self.assertRaises(exception.NotFound, self.store_api.get_from_backend, {}, image.locations[0]['url']) def _add_image(self, context, image_id, data, len): image_stub = ImageStub(image_id, status='queued', locations=[]) image = glance.store.ImageProxy(image_stub, context, self.store_api) image.set_data(data, len) self.assertEqual(image.size, len) #NOTE(markwash): FakeStore returns image_id for location location = {'url': image_id, 'metadata': {}} self.assertEqual(image.locations, [location]) self.assertEqual(image_stub.locations, [location]) self.assertEqual(image.status, 'active') return (image, image_stub) def test_image_change_append_invalid_location_uri(self): self.assertEqual(len(self.store_api.data.keys()), 2) context = glance.context.RequestContext(user=USER1) (image1, image_stub1) = self._add_image(context, UUID2, 'XXXX', 4) location_bad = {'url': 'unknown://location', 'metadata': {}} self.assertRaises(exception.BadStoreUri, image1.locations.append, location_bad) image1.delete() self.assertEqual(len(self.store_api.data.keys()), 2) self.assertFalse(UUID2 in self.store_api.data.keys()) def test_image_change_append_invalid_location_metatdata(self): UUID3 = 'a8a61ec4-d7a3-11e2-8c28-000c29c27581' self.assertEqual(len(self.store_api.data.keys()), 2) context = glance.context.RequestContext(user=USER1) (image1, image_stub1) = self._add_image(context, UUID2, 'XXXX', 4) (image2, image_stub2) = self._add_image(context, UUID3, 'YYYY', 4) # Using only one test rule here is enough to make sure # 'store.check_location_metadata()' can be triggered # in Location proxy layer. Complete test rule for # 'store.check_location_metadata()' testing please # check below cases within 'TestStoreMetaDataChecker'. location_bad = {'url': UUID3, 'metadata': "a invalid metadata"} self.assertRaises(glance.store.BackendException, image1.locations.append, location_bad) image1.delete() image2.delete() self.assertEqual(len(self.store_api.data.keys()), 2) self.assertFalse(UUID2 in self.store_api.data.keys()) self.assertFalse(UUID3 in self.store_api.data.keys()) def test_image_change_append_locations(self): UUID3 = 'a8a61ec4-d7a3-11e2-8c28-000c29c27581' self.assertEqual(len(self.store_api.data.keys()), 2) context = glance.context.RequestContext(user=USER1) (image1, image_stub1) = self._add_image(context, UUID2, 'XXXX', 4) (image2, image_stub2) = self._add_image(context, UUID3, 'YYYY', 4) location2 = {'url': UUID2, 'metadata': {}} location3 = {'url': UUID3, 'metadata': {}} image1.locations.append(location3) self.assertEqual(image_stub1.locations, [location2, location3]) self.assertEqual(image1.locations, [location2, location3]) image1.delete() self.assertEqual(len(self.store_api.data.keys()), 2) self.assertFalse(UUID2 in self.store_api.data.keys()) self.assertFalse(UUID3 in self.store_api.data.keys()) image2.delete() def test_image_change_pop_location(self): UUID3 = 'a8a61ec4-d7a3-11e2-8c28-000c29c27581' self.assertEqual(len(self.store_api.data.keys()), 2) context = glance.context.RequestContext(user=USER1) (image1, image_stub1) = self._add_image(context, UUID2, 'XXXX', 4) (image2, image_stub2) = self._add_image(context, UUID3, 'YYYY', 4) location2 = {'url': UUID2, 'metadata': {}} location3 = {'url': UUID3, 'metadata': {}} image1.locations.append(location3) self.assertEqual(image_stub1.locations, [location2, location3]) self.assertEqual(image1.locations, [location2, location3]) image1.locations.pop() self.assertEqual(image_stub1.locations, [location2]) self.assertEqual(image1.locations, [location2]) image1.delete() self.assertEqual(len(self.store_api.data.keys()), 2) self.assertFalse(UUID2 in self.store_api.data.keys()) self.assertFalse(UUID3 in self.store_api.data.keys()) image2.delete() def test_image_change_extend_invalid_locations_uri(self): self.assertEqual(len(self.store_api.data.keys()), 2) context = glance.context.RequestContext(user=USER1) (image1, image_stub1) = self._add_image(context, UUID2, 'XXXX', 4) location_bad = {'url': 'unknown://location', 'metadata': {}} self.assertRaises(exception.BadStoreUri, image1.locations.extend, [location_bad]) image1.delete() self.assertEqual(len(self.store_api.data.keys()), 2) self.assertFalse(UUID2 in self.store_api.data.keys()) def test_image_change_extend_invalid_locations_metadata(self): UUID3 = 'a8a61ec4-d7a3-11e2-8c28-000c29c27581' self.assertEqual(len(self.store_api.data.keys()), 2) context = glance.context.RequestContext(user=USER1) (image1, image_stub1) = self._add_image(context, UUID2, 'XXXX', 4) (image2, image_stub2) = self._add_image(context, UUID3, 'YYYY', 4) location_bad = {'url': UUID3, 'metadata': "a invalid metadata"} self.assertRaises(glance.store.BackendException, image1.locations.extend, [location_bad]) image1.delete() image2.delete() self.assertEqual(len(self.store_api.data.keys()), 2) self.assertFalse(UUID2 in self.store_api.data.keys()) self.assertFalse(UUID3 in self.store_api.data.keys()) def test_image_change_extend_locations(self): UUID3 = 'a8a61ec4-d7a3-11e2-8c28-000c29c27581' self.assertEqual(len(self.store_api.data.keys()), 2) context = glance.context.RequestContext(user=USER1) (image1, image_stub1) = self._add_image(context, UUID2, 'XXXX', 4) (image2, image_stub2) = self._add_image(context, UUID3, 'YYYY', 4) location2 = {'url': UUID2, 'metadata': {}} location3 = {'url': UUID3, 'metadata': {}} image1.locations.extend([location3]) self.assertEqual(image_stub1.locations, [location2, location3]) self.assertEqual(image1.locations, [location2, location3]) image1.delete() self.assertEqual(len(self.store_api.data.keys()), 2) self.assertFalse(UUID2 in self.store_api.data.keys()) self.assertFalse(UUID3 in self.store_api.data.keys()) image2.delete() def test_image_change_remove_location(self): UUID3 = 'a8a61ec4-d7a3-11e2-8c28-000c29c27581' self.assertEqual(len(self.store_api.data.keys()), 2) context = glance.context.RequestContext(user=USER1) (image1, image_stub1) = self._add_image(context, UUID2, 'XXXX', 4) (image2, image_stub2) = self._add_image(context, UUID3, 'YYYY', 4) location2 = {'url': UUID2, 'metadata': {}} location3 = {'url': UUID3, 'metadata': {}} location_bad = {'url': 'unknown://location', 'metadata': {}} image1.locations.extend([location3]) image1.locations.remove(location2) self.assertEqual(image_stub1.locations, [location3]) self.assertEqual(image1.locations, [location3]) self.assertRaises(ValueError, image1.locations.remove, location_bad) image1.delete() image2.delete() self.assertEqual(len(self.store_api.data.keys()), 2) self.assertFalse(UUID2 in self.store_api.data.keys()) self.assertFalse(UUID3 in self.store_api.data.keys()) def test_image_change_delete_location(self): self.assertEqual(len(self.store_api.data.keys()), 2) context = glance.context.RequestContext(user=USER1) (image1, image_stub1) = self._add_image(context, UUID2, 'XXXX', 4) del image1.locations[0] self.assertEqual(image_stub1.locations, []) self.assertEqual(len(image1.locations), 0) self.assertEqual(len(self.store_api.data.keys()), 2) self.assertFalse(UUID2 in self.store_api.data.keys()) image1.delete() def test_image_change_insert_invalid_location_uri(self): self.assertEqual(len(self.store_api.data.keys()), 2) context = glance.context.RequestContext(user=USER1) (image1, image_stub1) = self._add_image(context, UUID2, 'XXXX', 4) location_bad = {'url': 'unknown://location', 'metadata': {}} self.assertRaises(exception.BadStoreUri, image1.locations.insert, 0, location_bad) image1.delete() self.assertEqual(len(self.store_api.data.keys()), 2) self.assertFalse(UUID2 in self.store_api.data.keys()) def test_image_change_insert_invalid_location_metadata(self): UUID3 = 'a8a61ec4-d7a3-11e2-8c28-000c29c27581' self.assertEqual(len(self.store_api.data.keys()), 2) context = glance.context.RequestContext(user=USER1) (image1, image_stub1) = self._add_image(context, UUID2, 'XXXX', 4) (image2, image_stub2) = self._add_image(context, UUID3, 'YYYY', 4) location_bad = {'url': UUID3, 'metadata': "a invalid metadata"} self.assertRaises(glance.store.BackendException, image1.locations.insert, 0, location_bad) image1.delete() image2.delete() self.assertEqual(len(self.store_api.data.keys()), 2) self.assertFalse(UUID2 in self.store_api.data.keys()) self.assertFalse(UUID3 in self.store_api.data.keys()) def test_image_change_insert_location(self): UUID3 = 'a8a61ec4-d7a3-11e2-8c28-000c29c27581' self.assertEqual(len(self.store_api.data.keys()), 2) context = glance.context.RequestContext(user=USER1) (image1, image_stub1) = self._add_image(context, UUID2, 'XXXX', 4) (image2, image_stub2) = self._add_image(context, UUID3, 'YYYY', 4) location2 = {'url': UUID2, 'metadata': {}} location3 = {'url': UUID3, 'metadata': {}} image1.locations.insert(0, location3) self.assertEqual(image_stub1.locations, [location3, location2]) self.assertEqual(image1.locations, [location3, location2]) image1.delete() self.assertEqual(len(self.store_api.data.keys()), 2) self.assertFalse(UUID2 in self.store_api.data.keys()) self.assertFalse(UUID3 in self.store_api.data.keys()) image2.delete() def test_image_change_delete_locations(self): UUID3 = 'a8a61ec4-d7a3-11e2-8c28-000c29c27581' self.assertEqual(len(self.store_api.data.keys()), 2) context = glance.context.RequestContext(user=USER1) (image1, image_stub1) = self._add_image(context, UUID2, 'XXXX', 4) (image2, image_stub2) = self._add_image(context, UUID3, 'YYYY', 4) location2 = {'url': UUID2, 'metadata': {}} location3 = {'url': UUID3, 'metadata': {}} image1.locations.insert(0, location3) del image1.locations[0:100] self.assertEqual(image_stub1.locations, []) self.assertEqual(len(image1.locations), 0) self.assertRaises(exception.BadStoreUri, image1.locations.insert, 0, location2) self.assertRaises(exception.BadStoreUri, image2.locations.insert, 0, location3) image1.delete() image2.delete() self.assertEqual(len(self.store_api.data.keys()), 2) self.assertFalse(UUID2 in self.store_api.data.keys()) self.assertFalse(UUID3 in self.store_api.data.keys()) def test_image_change_adding_invalid_location_uri(self): self.assertEqual(len(self.store_api.data.keys()), 2) context = glance.context.RequestContext(user=USER1) image_stub1 = ImageStub('fake_image_id', status='queued', locations=[]) image1 = glance.store.ImageProxy(image_stub1, context, self.store_api) location_bad = {'url': 'unknown://location', 'metadata': {}} self.assertRaises(exception.BadStoreUri, image1.locations.__iadd__, [location_bad]) self.assertEqual(image_stub1.locations, []) self.assertEqual(image1.locations, []) image1.delete() self.assertEqual(len(self.store_api.data.keys()), 2) self.assertFalse(UUID2 in self.store_api.data.keys()) def test_image_change_adding_invalid_location_metadata(self): self.assertEqual(len(self.store_api.data.keys()), 2) context = glance.context.RequestContext(user=USER1) (image1, image_stub1) = self._add_image(context, UUID2, 'XXXX', 4) image_stub2 = ImageStub('fake_image_id', status='queued', locations=[]) image2 = glance.store.ImageProxy(image_stub2, context, self.store_api) location_bad = {'url': UUID2, 'metadata': "a invalid metadata"} self.assertRaises(glance.store.BackendException, image2.locations.__iadd__, [location_bad]) self.assertEqual(image_stub2.locations, []) self.assertEqual(image2.locations, []) image1.delete() image2.delete() self.assertEqual(len(self.store_api.data.keys()), 2) self.assertFalse(UUID2 in self.store_api.data.keys()) def test_image_change_adding_locations(self): UUID3 = 'a8a61ec4-d7a3-11e2-8c28-000c29c27581' self.assertEqual(len(self.store_api.data.keys()), 2) context = glance.context.RequestContext(user=USER1) (image1, image_stub1) = self._add_image(context, UUID2, 'XXXX', 4) (image2, image_stub2) = self._add_image(context, UUID3, 'YYYY', 4) image_stub3 = ImageStub('fake_image_id', status='queued', locations=[]) image3 = glance.store.ImageProxy(image_stub3, context, self.store_api) location2 = {'url': UUID2, 'metadata': {}} location3 = {'url': UUID3, 'metadata': {}} image3.locations += [location2, location3] self.assertEqual(image_stub3.locations, [location2, location3]) self.assertEqual(image3.locations, [location2, location3]) image3.delete() self.assertEqual(len(self.store_api.data.keys()), 2) self.assertFalse(UUID2 in self.store_api.data.keys()) self.assertFalse(UUID3 in self.store_api.data.keys()) image1.delete() image2.delete() def test_image_get_location_index(self): UUID3 = 'a8a61ec4-d7a3-11e2-8c28-000c29c27581' self.assertEqual(len(self.store_api.data.keys()), 2) context = glance.context.RequestContext(user=USER1) (image1, image_stub1) = self._add_image(context, UUID2, 'XXXX', 4) (image2, image_stub2) = self._add_image(context, UUID3, 'YYYY', 4) image_stub3 = ImageStub('fake_image_id', status='queued', locations=[]) image3 = glance.store.ImageProxy(image_stub3, context, self.store_api) location2 = {'url': UUID2, 'metadata': {}} location3 = {'url': UUID3, 'metadata': {}} image3.locations += [location2, location3] self.assertEqual(image_stub3.locations.index(location3), 1) image3.delete() self.assertEqual(len(self.store_api.data.keys()), 2) self.assertFalse(UUID2 in self.store_api.data.keys()) self.assertFalse(UUID3 in self.store_api.data.keys()) image1.delete() image2.delete() def test_image_get_location_by_index(self): UUID3 = 'a8a61ec4-d7a3-11e2-8c28-000c29c27581' self.assertEqual(len(self.store_api.data.keys()), 2) context = glance.context.RequestContext(user=USER1) (image1, image_stub1) = self._add_image(context, UUID2, 'XXXX', 4) (image2, image_stub2) = self._add_image(context, UUID3, 'YYYY', 4) image_stub3 = ImageStub('fake_image_id', status='queued', locations=[]) image3 = glance.store.ImageProxy(image_stub3, context, self.store_api) location2 = {'url': UUID2, 'metadata': {}} location3 = {'url': UUID3, 'metadata': {}} image3.locations += [location2, location3] self.assertEqual(image_stub3.locations.index(location3), 1) self.assertEqual(image_stub3.locations[0], location2) image3.delete() self.assertEqual(len(self.store_api.data.keys()), 2) self.assertFalse(UUID2 in self.store_api.data.keys()) self.assertFalse(UUID3 in self.store_api.data.keys()) image1.delete() image2.delete() def test_image_checking_location_exists(self): UUID3 = 'a8a61ec4-d7a3-11e2-8c28-000c29c27581' self.assertEqual(len(self.store_api.data.keys()), 2) context = glance.context.RequestContext(user=USER1) (image1, image_stub1) = self._add_image(context, UUID2, 'XXXX', 4) (image2, image_stub2) = self._add_image(context, UUID3, 'YYYY', 4) image_stub3 = ImageStub('fake_image_id', status='queued', locations=[]) image3 = glance.store.ImageProxy(image_stub3, context, self.store_api) location2 = {'url': UUID2, 'metadata': {}} location3 = {'url': UUID3, 'metadata': {}} location_bad = {'url': 'unknown://location', 'metadata': {}} image3.locations += [location2, location3] self.assertTrue(location3 in image_stub3.locations) self.assertFalse(location_bad in image_stub3.locations) image3.delete() self.assertEqual(len(self.store_api.data.keys()), 2) self.assertFalse(UUID2 in self.store_api.data.keys()) self.assertFalse(UUID3 in self.store_api.data.keys()) image1.delete() image2.delete() def test_image_reverse_locations_order(self): UUID3 = 'a8a61ec4-d7a3-11e2-8c28-000c29c27581' self.assertEqual(len(self.store_api.data.keys()), 2) context = glance.context.RequestContext(user=USER1) (image1, image_stub1) = self._add_image(context, UUID2, 'XXXX', 4) (image2, image_stub2) = self._add_image(context, UUID3, 'YYYY', 4) location2 = {'url': UUID2, 'metadata': {}} location3 = {'url': UUID3, 'metadata': {}} image_stub3 = ImageStub('fake_image_id', status='queued', locations=[]) image3 = glance.store.ImageProxy(image_stub3, context, self.store_api) image3.locations += [location2, location3] image_stub3.locations.reverse() self.assertEqual(image_stub3.locations, [location3, location2]) self.assertEqual(image3.locations, [location3, location2]) image3.delete() self.assertEqual(len(self.store_api.data.keys()), 2) self.assertFalse(UUID2 in self.store_api.data.keys()) self.assertFalse(UUID3 in self.store_api.data.keys()) image1.delete() image2.delete() class TestStoreImageRepo(utils.BaseTestCase): def setUp(self): super(TestStoreImageRepo, self).setUp() self.store_api = unit_test_utils.FakeStoreAPI() self.image_stub = ImageStub(UUID1) self.image = glance.store.ImageProxy(self.image_stub, {}, self.store_api) self.image_repo_stub = ImageRepoStub() self.image_repo = glance.store.ImageRepoProxy(self.image_repo_stub, {}, self.store_api) def test_add_updates_acls(self): self.image_stub.locations = [{'url': 'foo', 'metadata': {}}, {'url': 'bar', 'metadata': {}}] self.image_stub.visibility = 'public' self.image_repo.add(self.image) self.assertTrue(self.store_api.acls['foo']['public']) self.assertEqual(self.store_api.acls['foo']['read'], []) self.assertEqual(self.store_api.acls['foo']['write'], []) self.assertTrue(self.store_api.acls['bar']['public']) self.assertEqual(self.store_api.acls['bar']['read'], []) self.assertEqual(self.store_api.acls['bar']['write'], []) def test_add_ignores_acls_if_no_locations(self): self.image_stub.locations = [] self.image_stub.visibility = 'public' self.image_repo.add(self.image) self.assertEqual(len(self.store_api.acls), 0) def test_save_updates_acls(self): self.image_stub.locations = [{'url': 'foo', 'metadata': {}}] self.image_repo.save(self.image) self.assertIn('foo', self.store_api.acls) def test_add_fetches_members_if_private(self): self.image_stub.locations = [{'url': 'glue', 'metadata': {}}] self.image_stub.visibility = 'private' self.image_repo.add(self.image) self.assertIn('glue', self.store_api.acls) acls = self.store_api.acls['glue'] self.assertFalse(acls['public']) self.assertEqual(acls['write'], []) self.assertEqual(acls['read'], [TENANT1, TENANT2]) def test_save_fetches_members_if_private(self): self.image_stub.locations = [{'url': 'glue', 'metadata': {}}] self.image_stub.visibility = 'private' self.image_repo.save(self.image) self.assertIn('glue', self.store_api.acls) acls = self.store_api.acls['glue'] self.assertFalse(acls['public']) self.assertEqual(acls['write'], []) self.assertEqual(acls['read'], [TENANT1, TENANT2]) def test_member_addition_updates_acls(self): self.image_stub.locations = [{'url': 'glug', 'metadata': {}}] self.image_stub.visibility = 'private' member_repo = self.image.get_member_repo() membership = glance.domain.ImageMembership( UUID1, TENANT3, None, None, status='accepted') member_repo.add(membership) self.assertIn('glug', self.store_api.acls) acls = self.store_api.acls['glug'] self.assertFalse(acls['public']) self.assertEqual(acls['write'], []) self.assertEqual(acls['read'], [TENANT1, TENANT2, TENANT3]) def test_member_removal_updates_acls(self): self.image_stub.locations = [{'url': 'glug', 'metadata': {}}] self.image_stub.visibility = 'private' member_repo = self.image.get_member_repo() membership = glance.domain.ImageMembership( UUID1, TENANT1, None, None, status='accepted') member_repo.remove(membership) self.assertIn('glug', self.store_api.acls) acls = self.store_api.acls['glug'] self.assertFalse(acls['public']) self.assertEqual(acls['write'], []) self.assertEqual(acls['read'], [TENANT2]) class TestImageFactory(utils.BaseTestCase): def setUp(self): super(TestImageFactory, self).setUp() self.image_factory = glance.store.ImageFactoryProxy( ImageFactoryStub(), glance.context.RequestContext(user=USER1), unit_test_utils.FakeStoreAPI()) def test_new_image(self): image = self.image_factory.new_image() self.assertTrue(image.image_id is None) self.assertTrue(image.status is None) self.assertEqual(image.visibility, 'private') self.assertEqual(image.locations, []) def test_new_image_with_location(self): locations = [{'url': '%s/%s' % (BASE_URI, UUID1), 'metadata': {}}] image = self.image_factory.new_image(locations=locations) self.assertEqual(image.locations, locations) location_bad = {'url': 'unknown://location', 'metadata': {}} self.assertRaises(exception.BadStoreUri, self.image_factory.new_image, locations=[location_bad]) class TestStoreMetaDataChecker(utils.BaseTestCase): def test_empty(self): glance.store.check_location_metadata({}) def test_unicode(self): m = {'key': u'somevalue'} glance.store.check_location_metadata(m) def test_unicode_list(self): m = {'key': [u'somevalue', u'2']} glance.store.check_location_metadata(m) def test_unicode_dict(self): inner = {'key1': u'somevalue', 'key2': u'somevalue'} m = {'topkey': inner} glance.store.check_location_metadata(m) def test_unicode_dict_list(self): inner = {'key1': u'somevalue', 'key2': u'somevalue'} m = {'topkey': inner, 'list': [u'somevalue', u'2'], 'u': u'2'} glance.store.check_location_metadata(m) def test_nested_dict(self): inner = {'key1': u'somevalue', 'key2': u'somevalue'} inner = {'newkey': inner} inner = {'anotherkey': inner} m = {'topkey': inner} glance.store.check_location_metadata(m) def test_simple_bad(self): m = {'key1': object()} self.assertRaises(glance.store.BackendException, glance.store.check_location_metadata, m) def test_list_bad(self): m = {'key1': [u'somevalue', object()]} self.assertRaises(glance.store.BackendException, glance.store.check_location_metadata, m) def test_nested_dict_bad(self): inner = {'key1': u'somevalue', 'key2': object()} inner = {'newkey': inner} inner = {'anotherkey': inner} m = {'topkey': inner} self.assertRaises(glance.store.BackendException, glance.store.check_location_metadata, m) class TestStoreAddToBackend(utils.BaseTestCase): def setUp(self): super(TestStoreAddToBackend, self).setUp() self.image_id = "animage" self.data = "dataandstuff" self.size = len(self.data) self.location = "file:///ab/cde/fgh" self.checksum = "md5" self.mox = mox.Mox() def tearDown(self): super(TestStoreAddToBackend, self).tearDown() self.mox.UnsetStubs() def _bad_metadata(self, in_metadata): store = self.mox.CreateMockAnything() store.add(self.image_id, mox.IgnoreArg(), self.size).AndReturn( (self.location, self.size, self.checksum, in_metadata)) store.__str__ = lambda: "hello" store.__unicode__ = lambda: "hello" self.mox.ReplayAll() self.assertRaises(glance.store.BackendException, glance.store.store_add_to_backend, self.image_id, self.data, self.size, store) self.mox.VerifyAll() def _good_metadata(self, in_metadata): store = self.mox.CreateMockAnything() store.add(self.image_id, mox.IgnoreArg(), self.size).AndReturn( (self.location, self.size, self.checksum, in_metadata)) self.mox.ReplayAll() (location, size, checksum, metadata) = glance.store.store_add_to_backend(self.image_id, self.data, self.size, store) self.mox.VerifyAll() self.assertEqual(self.location, location) self.assertEqual(self.size, size) self.assertEqual(self.checksum, checksum) self.assertEqual(in_metadata, metadata) def test_empty(self): metadata = {} self._good_metadata(metadata) def test_string(self): metadata = {'key': u'somevalue'} self._good_metadata(metadata) def test_list(self): m = {'key': [u'somevalue', u'2']} self._good_metadata(m) def test_unicode_dict(self): inner = {'key1': u'somevalue', 'key2': u'somevalue'} m = {'topkey': inner} self._good_metadata(m) def test_unicode_dict_list(self): inner = {'key1': u'somevalue', 'key2': u'somevalue'} m = {'topkey': inner, 'list': [u'somevalue', u'2'], 'u': u'2'} self._good_metadata(m) def test_nested_dict(self): inner = {'key1': u'somevalue', 'key2': u'somevalue'} inner = {'newkey': inner} inner = {'anotherkey': inner} m = {'topkey': inner} self._good_metadata(m) def test_bad_top_level_nonunicode(self): metadata = {'key': 'a string'} self._bad_metadata(metadata) def test_bad_nonunicode_dict_list(self): inner = {'key1': u'somevalue', 'key2': u'somevalue', 'k3': [1, object()]} m = {'topkey': inner, 'list': [u'somevalue', u'2'], 'u': u'2'} self._bad_metadata(m) def test_bad_metadata_not_dict(self): store = self.mox.CreateMockAnything() store.add(self.image_id, mox.IgnoreArg(), self.size).AndReturn( (self.location, self.size, self.checksum, [])) store.__str__ = lambda: "hello" store.__unicode__ = lambda: "hello" self.mox.ReplayAll() self.assertRaises(glance.store.BackendException, glance.store.store_add_to_backend, self.image_id, self.data, self.size, store) self.mox.VerifyAll() glance-2014.1/glance/tests/unit/test_image_cache_client.py0000664000175400017540000001107012323736226024723 0ustar jenkinsjenkins00000000000000# Copyright 2013 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import mock import os from glance.common import exception from glance.image_cache import client from glance.tests import utils class CacheClientTestCase(utils.BaseTestCase): def setUp(self): super(CacheClientTestCase, self).setUp() self.client = client.CacheClient('test_host') self.client.do_request = mock.Mock() def test_delete_cached_image(self): self.client.do_request.return_value = utils.FakeHTTPResponse() self.assertTrue(self.client.delete_cached_image('test_id')) self.client.do_request.assert_called_with("DELETE", "/cached_images/test_id") def test_get_cached_images(self): expected_data = '{"cached_images": "some_images"}' self.client.do_request.return_value = \ utils.FakeHTTPResponse(data=expected_data) self.assertEqual(self.client.get_cached_images(), "some_images") self.client.do_request.assert_called_with("GET", "/cached_images") def test_get_queued_images(self): expected_data = '{"queued_images": "some_images"}' self.client.do_request.return_value = \ utils.FakeHTTPResponse(data=expected_data) self.assertEqual(self.client.get_queued_images(), "some_images") self.client.do_request.assert_called_with("GET", "/queued_images") def test_delete_all_cached_images(self): expected_data = '{"num_deleted": 4}' self.client.do_request.return_value = \ utils.FakeHTTPResponse(data=expected_data) self.assertEqual(self.client.delete_all_cached_images(), 4) self.client.do_request.assert_called_with("DELETE", "/cached_images") def test_queue_image_for_caching(self): self.client.do_request.return_value = utils.FakeHTTPResponse() self.assertTrue(self.client.queue_image_for_caching('test_id')) self.client.do_request.assert_called_with("PUT", "/queued_images/test_id") def test_delete_queued_image(self): self.client.do_request.return_value = utils.FakeHTTPResponse() self.assertTrue(self.client.delete_queued_image('test_id')) self.client.do_request.assert_called_with("DELETE", "/queued_images/test_id") def test_delete_all_queued_images(self): expected_data = '{"num_deleted": 4}' self.client.do_request.return_value = \ utils.FakeHTTPResponse(data=expected_data) self.assertEqual(self.client.delete_all_queued_images(), 4) self.client.do_request.assert_called_with("DELETE", "/queued_images") class GetClientTestCase(utils.BaseTestCase): def setUp(self): super(GetClientTestCase, self).setUp() self.host = 'test_host' def test_get_client_host_only(self): expected_creds = { 'username': None, 'password': None, 'tenant': None, 'auth_url': os.getenv('OS_AUTH_URL'), 'strategy': 'noauth', 'region': None } self.assertEqual(client.get_client(self.host).creds, expected_creds) def test_get_client_all_creds(self): expected_creds = { 'username': 'name', 'password': 'pass', 'tenant': 'ten', 'auth_url': 'url', 'strategy': 'keystone', 'region': 'reg' } creds = client.get_client( self.host, username='name', password='pass', tenant='ten', auth_url='url', auth_strategy='strategy', region='reg' ).creds self.assertEqual(creds, expected_creds) def test_get_client_client_configuration_error(self): self.assertRaises(exception.ClientConfigurationError, client.get_client, self.host, username='name', password='pass', tenant='ten', auth_strategy='keystone', region='reg') glance-2014.1/glance/tests/unit/fake_rados.py0000664000175400017540000000611612323736226022224 0ustar jenkinsjenkins00000000000000# Copyright 2013 Canonical Ltd. # 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. class mock_rados(object): class ioctx(object): def __init__(self, *args, **kwargs): pass def __enter__(self, *args, **kwargs): return self def __exit__(self, *args, **kwargs): return False def close(self, *args, **kwargs): pass class Rados(object): def __init__(self, *args, **kwargs): pass def __enter__(self, *args, **kwargs): return self def __exit__(self, *args, **kwargs): return False def connect(self, *args, **kwargs): pass def open_ioctx(self, *args, **kwargs): return mock_rados.ioctx() def shutdown(self, *args, **kwargs): pass class mock_rbd(object): class ImageExists(Exception): pass class ImageBusy(Exception): pass class ImageNotFound(Exception): pass class Image(object): def __init__(self, *args, **kwargs): pass def __enter__(self, *args, **kwargs): return self def __exit__(self, *args, **kwargs): pass def create_snap(self, *args, **kwargs): pass def remove_snap(self, *args, **kwargs): pass def protect_snap(self, *args, **kwargs): pass def unprotect_snap(self, *args, **kwargs): pass def read(self, *args, **kwargs): raise NotImplementedError() def write(self, *args, **kwargs): raise NotImplementedError() def resize(self, *args, **kwargs): raise NotImplementedError() def discard(self, offset, length): raise NotImplementedError() def close(self): pass def list_snaps(self): raise NotImplementedError() def parent_info(self): raise NotImplementedError() def size(self): raise NotImplementedError() class RBD(object): def __init__(self, *args, **kwargs): pass def __enter__(self, *args, **kwargs): return self def __exit__(self, *args, **kwargs): return False def create(self, *args, **kwargs): pass def remove(self, *args, **kwargs): pass def list(self, *args, **kwargs): raise NotImplementedError() def clone(self, *args, **kwargs): raise NotImplementedError() glance-2014.1/glance/tests/unit/test_context_middleware.py0000664000175400017540000001307612323736226025051 0ustar jenkinsjenkins00000000000000# 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 webob from glance.api.middleware import context import glance.context from glance.tests.unit import base class TestContextMiddleware(base.IsolatedUnitTest): def _build_request(self, roles=None, identity_status='Confirmed', service_catalog=None): req = webob.Request.blank('/') req.headers['x-auth-token'] = 'token1' req.headers['x-identity-status'] = identity_status req.headers['x-user-id'] = 'user1' req.headers['x-tenant-id'] = 'tenant1' _roles = roles or ['role1', 'role2'] req.headers['x-roles'] = ','.join(_roles) if service_catalog: req.headers['x-service-catalog'] = service_catalog return req def _build_middleware(self): return context.ContextMiddleware(None) def test_header_parsing(self): req = self._build_request() self._build_middleware().process_request(req) self.assertEqual(req.context.auth_tok, 'token1') self.assertEqual(req.context.user, 'user1') self.assertEqual(req.context.tenant, 'tenant1') self.assertEqual(req.context.roles, ['role1', 'role2']) def test_is_admin_flag(self): # is_admin check should look for 'admin' role by default req = self._build_request(roles=['admin', 'role2']) self._build_middleware().process_request(req) self.assertTrue(req.context.is_admin) # without the 'admin' role, is_admin should be False req = self._build_request() self._build_middleware().process_request(req) self.assertFalse(req.context.is_admin) # if we change the admin_role attribute, we should be able to use it req = self._build_request() self.config(admin_role='role1') self._build_middleware().process_request(req) self.assertTrue(req.context.is_admin) def test_roles_case_insensitive(self): # accept role from request req = self._build_request(roles=['Admin', 'role2']) self._build_middleware().process_request(req) self.assertTrue(req.context.is_admin) # accept role from config req = self._build_request(roles=['role1']) self.config(admin_role='rOLe1') self._build_middleware().process_request(req) self.assertTrue(req.context.is_admin) def test_roles_stripping(self): # stripping extra spaces in request req = self._build_request(roles=['\trole1']) self.config(admin_role='role1') self._build_middleware().process_request(req) self.assertTrue(req.context.is_admin) # stripping extra spaces in config req = self._build_request(roles=['\trole1\n']) self.config(admin_role=' role1\t') self._build_middleware().process_request(req) self.assertTrue(req.context.is_admin) def test_anonymous_access_enabled(self): req = self._build_request(identity_status='Nope') self.config(allow_anonymous_access=True) middleware = self._build_middleware() middleware.process_request(req) self.assertIsNone(req.context.auth_tok) self.assertIsNone(req.context.user) self.assertIsNone(req.context.tenant) self.assertEqual(req.context.roles, []) self.assertFalse(req.context.is_admin) self.assertTrue(req.context.read_only) def test_anonymous_access_defaults_to_disabled(self): req = self._build_request(identity_status='Nope') middleware = self._build_middleware() self.assertRaises(webob.exc.HTTPUnauthorized, middleware.process_request, req) def test_service_catalog(self): catalog_json = "[{}]" req = self._build_request(service_catalog=catalog_json) self._build_middleware().process_request(req) self.assertEqual([{}], req.context.service_catalog) def test_invalid_service_catalog(self): catalog_json = "bad json" req = self._build_request(service_catalog=catalog_json) middleware = self._build_middleware() self.assertRaises(webob.exc.HTTPInternalServerError, middleware.process_request, req) class TestUnauthenticatedContextMiddleware(base.IsolatedUnitTest): def test_request(self): middleware = context.UnauthenticatedContextMiddleware(None) req = webob.Request.blank('/') middleware.process_request(req) self.assertIsNone(req.context.auth_tok) self.assertIsNone(req.context.user) self.assertIsNone(req.context.tenant) self.assertEqual(req.context.roles, []) self.assertTrue(req.context.is_admin) def test_response(self): middleware = context.UnauthenticatedContextMiddleware(None) req = webob.Request.blank('/') req.context = glance.context.RequestContext() resp = webob.Response() resp.request = req middleware.process_response(resp) self.assertEqual(resp.headers['x-openstack-request-id'], 'req-%s' % req.context.request_id) glance-2014.1/glance/tests/unit/test_cached_images.py0000664000175400017540000000664112323736226023724 0ustar jenkinsjenkins00000000000000# Copyright (C) 2013 Yahoo! 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. import testtools import webob from glance.api import cached_images from glance.api import policy from glance.common import exception from glance import image_cache class FakePolicyEnforcer(policy.Enforcer): def __init__(self): self.default_rule = '' self.policy_path = '' self.policy_file_mtime = None self.policy_file_contents = None def enforce(self, context, action, target): return 'pass' def check(rule, target, creds, exc=None, *args, **kwargs): return 'pass' def _check(self, context, rule, target, *args, **kwargs): return 'pass' class FakeCache(image_cache.ImageCache): def __init__(self): self.init_driver() self.deleted_images = [] def init_driver(self): pass def get_cached_images(self): return {'id': 'test'} def delete_cached_image(self, image_id): self.deleted_images.append(image_id) def get_queued_images(self): return {'test': 'passed'} def queue_image(self, image_id): return 'pass' def delete_queued_image(self, image_id): self.deleted_images.append(image_id) class FakeController(cached_images.Controller): def __init__(self): self.cache = FakeCache() self.policy = FakePolicyEnforcer() class TestController(testtools.TestCase): def test_initialization_without_conf(self): self.assertRaises(exception.BadDriverConfiguration, cached_images.Controller) class TestCachedImages(testtools.TestCase): def setUp(self): super(TestCachedImages, self).setUp() test_controller = FakeController() self.controller = test_controller def test_get_cached_images(self): req = webob.Request.blank('') req.context = 'test' result = self.controller.get_cached_images(req) self.assertEqual({'cached_images': {'id': 'test'}}, result) def test_delete_cached_images(self): req = webob.Request.blank('') req.context = 'test' self.controller.delete_cached_image(req, image_id='test') self.assertEqual(['test'], self.controller.cache.deleted_images) def test_get_queued_images(self): req = webob.Request.blank('') req.context = 'test' result = self.controller.get_queued_images(req) self.assertEqual({'queued_images': {'test': 'passed'}}, result) def test_queue_image(self): req = webob.Request.blank('') req.context = 'test' self.controller.queue_image(req, image_id='test1') def test_delete_queued_image(self): req = webob.Request.blank('') req.context = 'test' self.controller.delete_queued_image(req, 'deleted_img') self.assertEqual(['deleted_img'], self.controller.cache.deleted_images) glance-2014.1/glance/tests/unit/test_migrations.conf0000664000175400017540000000044712323736226023637 0ustar jenkinsjenkins00000000000000[DEFAULT] # Set up any number of migration data stores you want, one # The "name" used in the test is the config variable key. sqlite=sqlite:///test_migrations.db #mysql=mysql://root:@localhost/test_migrations #postgresql=postgresql://root:@localhost/test_migrations [walk_style] snake_walk=yes glance-2014.1/glance/tests/unit/test_swift_store.py0000664000175400017540000012171612323736226023541 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """Tests the Swift backend store""" import hashlib import httplib import mock import tempfile import uuid from oslo.config import cfg import six import six.moves.urllib.parse as urlparse import stubout import swiftclient import glance.common.auth from glance.common import exception from glance.openstack.common import units from glance.store import BackendException from glance.store.location import get_location_from_uri from glance.store.swift import swift_retry_iter from glance.tests.unit import base CONF = cfg.CONF FAKE_UUID = lambda: str(uuid.uuid4()) Store = glance.store.swift.Store FIVE_KB = 5 * units.Ki FIVE_GB = 5 * units.Gi MAX_SWIFT_OBJECT_SIZE = FIVE_GB SWIFT_PUT_OBJECT_CALLS = 0 SWIFT_CONF = {'verbose': True, 'debug': True, 'known_stores': ['glance.store.swift.Store'], 'default_store': 'swift', 'swift_store_user': 'user', 'swift_store_key': 'key', 'swift_store_auth_address': 'localhost:8080', 'swift_store_container': 'glance', 'swift_store_retry_get_count': 1} # We stub out as little as possible to ensure that the code paths # between glance.store.swift and swiftclient are tested # thoroughly def stub_out_swiftclient(stubs, swift_store_auth_version): fixture_containers = ['glance'] fixture_container_headers = {} fixture_headers = { 'glance/%s' % FAKE_UUID: { 'content-length': FIVE_KB, 'etag': 'c2e5db72bd7fd153f53ede5da5a06de3' } } fixture_objects = {'glance/%s' % FAKE_UUID: six.StringIO("*" * FIVE_KB)} def fake_head_container(url, token, container, **kwargs): if container not in fixture_containers: msg = "No container %s found" % container raise swiftclient.ClientException(msg, http_status=httplib.NOT_FOUND) return fixture_container_headers def fake_put_container(url, token, container, **kwargs): fixture_containers.append(container) def fake_post_container(url, token, container, headers, http_conn=None): for key, value in headers.iteritems(): fixture_container_headers[key] = value def fake_put_object(url, token, container, name, contents, **kwargs): # PUT returns the ETag header for the newly-added object # Large object manifest... global SWIFT_PUT_OBJECT_CALLS SWIFT_PUT_OBJECT_CALLS += 1 CHUNKSIZE = 64 * units.Ki fixture_key = "%s/%s" % (container, name) if fixture_key not in fixture_headers: if kwargs.get('headers'): etag = kwargs['headers']['ETag'] fixture_headers[fixture_key] = {'manifest': True, 'etag': etag} return etag if hasattr(contents, 'read'): fixture_object = six.StringIO() chunk = contents.read(CHUNKSIZE) checksum = hashlib.md5() while chunk: fixture_object.write(chunk) checksum.update(chunk) chunk = contents.read(CHUNKSIZE) etag = checksum.hexdigest() else: fixture_object = six.StringIO(contents) etag = hashlib.md5(fixture_object.getvalue()).hexdigest() read_len = fixture_object.len if read_len > MAX_SWIFT_OBJECT_SIZE: msg = ('Image size:%d exceeds Swift max:%d' % (read_len, MAX_SWIFT_OBJECT_SIZE)) raise swiftclient.ClientException( msg, http_status=httplib.REQUEST_ENTITY_TOO_LARGE) fixture_objects[fixture_key] = fixture_object fixture_headers[fixture_key] = { 'content-length': read_len, 'etag': etag} return etag else: msg = ("Object PUT failed - Object with key %s already exists" % fixture_key) raise swiftclient.ClientException(msg, http_status=httplib.CONFLICT) def fake_get_object(url, token, container, name, **kwargs): # GET returns the tuple (list of headers, file object) fixture_key = "%s/%s" % (container, name) if fixture_key not in fixture_headers: msg = "Object GET failed" raise swiftclient.ClientException(msg, http_status=httplib.NOT_FOUND) byte_range = None headers = kwargs.get('headers', dict()) if headers is not None: headers = dict((k.lower(), v) for k, v in headers.iteritems()) if 'range' in headers: byte_range = headers.get('range') fixture = fixture_headers[fixture_key] if 'manifest' in fixture: # Large object manifest... we return a file containing # all objects with prefix of this fixture key chunk_keys = sorted([k for k in fixture_headers.keys() if k.startswith(fixture_key) and k != fixture_key]) result = six.StringIO() for key in chunk_keys: result.write(fixture_objects[key].getvalue()) else: result = fixture_objects[fixture_key] if byte_range is not None: start = int(byte_range.split('=')[1].strip('-')) result = six.StringIO(result.getvalue()[start:]) fixture_headers[fixture_key]['content-length'] = len( result.getvalue()) return fixture_headers[fixture_key], result def fake_head_object(url, token, container, name, **kwargs): # HEAD returns the list of headers for an object try: fixture_key = "%s/%s" % (container, name) return fixture_headers[fixture_key] except KeyError: msg = "Object HEAD failed - Object does not exist" raise swiftclient.ClientException(msg, http_status=httplib.NOT_FOUND) def fake_delete_object(url, token, container, name, **kwargs): # DELETE returns nothing fixture_key = "%s/%s" % (container, name) if fixture_key not in fixture_headers: msg = "Object DELETE failed - Object does not exist" raise swiftclient.ClientException(msg, http_status=httplib.NOT_FOUND) else: del fixture_headers[fixture_key] del fixture_objects[fixture_key] def fake_http_connection(*args, **kwargs): return None def fake_get_auth(url, user, key, snet, auth_version, **kwargs): if url is None: return None, None if 'http' in url and '://' not in url: raise ValueError('Invalid url %s' % url) # Check the auth version against the configured value if swift_store_auth_version != auth_version: msg = 'AUTHENTICATION failed (version mismatch)' raise swiftclient.ClientException(msg) return None, None stubs.Set(swiftclient.client, 'head_container', fake_head_container) stubs.Set(swiftclient.client, 'put_container', fake_put_container) stubs.Set(swiftclient.client, 'post_container', fake_post_container) stubs.Set(swiftclient.client, 'put_object', fake_put_object) stubs.Set(swiftclient.client, 'delete_object', fake_delete_object) stubs.Set(swiftclient.client, 'head_object', fake_head_object) stubs.Set(swiftclient.client, 'get_object', fake_get_object) stubs.Set(swiftclient.client, 'get_auth', fake_get_auth) stubs.Set(swiftclient.client, 'http_connection', fake_http_connection) class SwiftTests(object): @property def swift_store_user(self): return urlparse.quote(CONF.swift_store_user) def test_get_size(self): """ Test that we can get the size of an object in the swift store """ uri = "swift://%s:key@auth_address/glance/%s" % ( self.swift_store_user, FAKE_UUID) loc = get_location_from_uri(uri) image_size = self.store.get_size(loc) self.assertEqual(image_size, 5120) def test_get_size_with_multi_tenant_on(self): """Test that single tenant uris work with multi tenant on.""" uri = ("swift://%s:key@auth_address/glance/%s" % (self.swift_store_user, FAKE_UUID)) self.config(swift_store_multi_tenant=True) #NOTE(markwash): ensure the image is found context = glance.context.RequestContext() size = glance.store.get_size_from_backend(context, uri) self.assertEqual(size, 5120) def test_get(self): """Test a "normal" retrieval of an image in chunks""" uri = "swift://%s:key@auth_address/glance/%s" % ( self.swift_store_user, FAKE_UUID) loc = get_location_from_uri(uri) (image_swift, image_size) = self.store.get(loc) self.assertEqual(image_size, 5120) expected_data = "*" * FIVE_KB data = "" for chunk in image_swift: data += chunk self.assertEqual(expected_data, data) def test_get_with_retry(self): """ Test a retrieval where Swift does not get the full image in a single request. """ uri = "swift://%s:key@auth_address/glance/%s" % ( self.swift_store_user, FAKE_UUID) loc = get_location_from_uri(uri) (image_swift, image_size) = self.store.get(loc) resp_full = ''.join([chunk for chunk in image_swift.wrapped]) resp_half = resp_full[:len(resp_full) / 2] image_swift.wrapped = swift_retry_iter(resp_half, image_size, self.store, loc.store_location) self.assertEqual(image_size, 5120) expected_data = "*" * FIVE_KB data = "" for chunk in image_swift: data += chunk self.assertEqual(expected_data, data) def test_get_with_http_auth(self): """ Test a retrieval from Swift with an HTTP authurl. This is specified either via a Location header with swift+http:// or using http:// in the swift_store_auth_address config value """ loc = get_location_from_uri("swift+http://%s:key@auth_address/" "glance/%s" % (self.swift_store_user, FAKE_UUID)) (image_swift, image_size) = self.store.get(loc) self.assertEqual(image_size, 5120) expected_data = "*" * FIVE_KB data = "" for chunk in image_swift: data += chunk self.assertEqual(expected_data, data) def test_get_non_existing(self): """ Test that trying to retrieve a swift that doesn't exist raises an error """ loc = get_location_from_uri("swift://%s:key@authurl/glance/noexist" % ( self.swift_store_user)) self.assertRaises(exception.NotFound, self.store.get, loc) def test_add(self): """Test that we can add an image via the swift backend""" expected_swift_size = FIVE_KB expected_swift_contents = "*" * expected_swift_size expected_checksum = hashlib.md5(expected_swift_contents).hexdigest() expected_image_id = str(uuid.uuid4()) loc = 'swift+https://%s:key@localhost:8080/glance/%s' expected_location = loc % (self.swift_store_user, expected_image_id) image_swift = six.StringIO(expected_swift_contents) global SWIFT_PUT_OBJECT_CALLS SWIFT_PUT_OBJECT_CALLS = 0 location, size, checksum, _ = self.store.add(expected_image_id, image_swift, expected_swift_size) self.assertEqual(expected_location, location) self.assertEqual(expected_swift_size, size) self.assertEqual(expected_checksum, checksum) # Expecting a single object to be created on Swift i.e. no chunking. self.assertEqual(SWIFT_PUT_OBJECT_CALLS, 1) loc = get_location_from_uri(expected_location) (new_image_swift, new_image_size) = self.store.get(loc) new_image_contents = ''.join([chunk for chunk in new_image_swift]) new_image_swift_size = len(new_image_swift) self.assertEqual(expected_swift_contents, new_image_contents) self.assertEqual(expected_swift_size, new_image_swift_size) def test_add_auth_url_variations(self): """ Test that we can add an image via the swift backend with a variety of different auth_address values """ variations = { 'http://localhost:80': 'swift+http://%s:key@localhost:80' '/glance/%s', 'http://localhost': 'swift+http://%s:key@localhost/glance/%s', 'http://localhost/v1': 'swift+http://%s:key@localhost' '/v1/glance/%s', 'http://localhost/v1/': 'swift+http://%s:key@localhost' '/v1/glance/%s', 'https://localhost': 'swift+https://%s:key@localhost/glance/%s', 'https://localhost:8080': 'swift+https://%s:key@localhost:8080' '/glance/%s', 'https://localhost/v1': 'swift+https://%s:key@localhost' '/v1/glance/%s', 'https://localhost/v1/': 'swift+https://%s:key@localhost' '/v1/glance/%s', 'localhost': 'swift+https://%s:key@localhost/glance/%s', 'localhost:8080/v1': 'swift+https://%s:key@localhost:8080' '/v1/glance/%s', } for variation, expected_location in variations.items(): image_id = str(uuid.uuid4()) expected_location = expected_location % ( self.swift_store_user, image_id) expected_swift_size = FIVE_KB expected_swift_contents = "*" * expected_swift_size expected_checksum = \ hashlib.md5(expected_swift_contents).hexdigest() image_swift = six.StringIO(expected_swift_contents) global SWIFT_PUT_OBJECT_CALLS SWIFT_PUT_OBJECT_CALLS = 0 self.config(swift_store_auth_address=variation) self.store = Store() location, size, checksum, _ = self.store.add(image_id, image_swift, expected_swift_size) self.assertEqual(expected_location, location) self.assertEqual(expected_swift_size, size) self.assertEqual(expected_checksum, checksum) self.assertEqual(SWIFT_PUT_OBJECT_CALLS, 1) loc = get_location_from_uri(expected_location) (new_image_swift, new_image_size) = self.store.get(loc) new_image_contents = ''.join([chunk for chunk in new_image_swift]) new_image_swift_size = len(new_image_swift) self.assertEqual(expected_swift_contents, new_image_contents) self.assertEqual(expected_swift_size, new_image_swift_size) def test_add_no_container_no_create(self): """ Tests that adding an image with a non-existing container raises an appropriate exception """ self.config(swift_store_create_container_on_put=False, swift_store_container='noexist') self.store = Store() image_swift = six.StringIO("nevergonnamakeit") global SWIFT_PUT_OBJECT_CALLS SWIFT_PUT_OBJECT_CALLS = 0 # We check the exception text to ensure the container # missing text is found in it, otherwise, we would have # simply used self.assertRaises here exception_caught = False try: self.store.add(str(uuid.uuid4()), image_swift, 0) except BackendException as e: exception_caught = True self.assertTrue("container noexist does not exist " "in Swift" in six.text_type(e)) self.assertTrue(exception_caught) self.assertEqual(SWIFT_PUT_OBJECT_CALLS, 0) def test_add_no_container_and_create(self): """ Tests that adding an image with a non-existing container creates the container automatically if flag is set """ expected_swift_size = FIVE_KB expected_swift_contents = "*" * expected_swift_size expected_checksum = hashlib.md5(expected_swift_contents).hexdigest() expected_image_id = str(uuid.uuid4()) loc = 'swift+https://%s:key@localhost:8080/noexist/%s' expected_location = loc % (self.swift_store_user, expected_image_id) image_swift = six.StringIO(expected_swift_contents) global SWIFT_PUT_OBJECT_CALLS SWIFT_PUT_OBJECT_CALLS = 0 self.config(swift_store_create_container_on_put=True, swift_store_container='noexist') self.store = Store() location, size, checksum, _ = self.store.add(expected_image_id, image_swift, expected_swift_size) self.assertEqual(expected_location, location) self.assertEqual(expected_swift_size, size) self.assertEqual(expected_checksum, checksum) self.assertEqual(SWIFT_PUT_OBJECT_CALLS, 1) loc = get_location_from_uri(expected_location) (new_image_swift, new_image_size) = self.store.get(loc) new_image_contents = ''.join([chunk for chunk in new_image_swift]) new_image_swift_size = len(new_image_swift) self.assertEqual(expected_swift_contents, new_image_contents) self.assertEqual(expected_swift_size, new_image_swift_size) def test_add_large_object(self): """ Tests that adding a very large image. We simulate the large object by setting store.large_object_size to a small number and then verify that there have been a number of calls to put_object()... """ expected_swift_size = FIVE_KB expected_swift_contents = "*" * expected_swift_size expected_checksum = hashlib.md5(expected_swift_contents).hexdigest() expected_image_id = str(uuid.uuid4()) loc = 'swift+https://%s:key@localhost:8080/glance/%s' expected_location = loc % (self.swift_store_user, expected_image_id) image_swift = six.StringIO(expected_swift_contents) global SWIFT_PUT_OBJECT_CALLS SWIFT_PUT_OBJECT_CALLS = 0 self.config(swift_store_container='glance') self.store = Store() orig_max_size = self.store.large_object_size orig_temp_size = self.store.large_object_chunk_size try: self.store.large_object_size = 1024 self.store.large_object_chunk_size = 1024 location, size, checksum, _ = self.store.add(expected_image_id, image_swift, expected_swift_size) finally: self.store.large_object_chunk_size = orig_temp_size self.store.large_object_size = orig_max_size self.assertEqual(expected_location, location) self.assertEqual(expected_swift_size, size) self.assertEqual(expected_checksum, checksum) # Expecting 6 objects to be created on Swift -- 5 chunks and 1 # manifest. self.assertEqual(SWIFT_PUT_OBJECT_CALLS, 6) loc = get_location_from_uri(expected_location) (new_image_swift, new_image_size) = self.store.get(loc) new_image_contents = ''.join([chunk for chunk in new_image_swift]) new_image_swift_size = len(new_image_contents) self.assertEqual(expected_swift_contents, new_image_contents) self.assertEqual(expected_swift_size, new_image_swift_size) def test_add_large_object_zero_size(self): """ Tests that adding an image to Swift which has both an unknown size and exceeds Swift's maximum limit of 5GB is correctly uploaded. We avoid the overhead of creating a 5GB object for this test by temporarily setting MAX_SWIFT_OBJECT_SIZE to 1KB, and then adding an object of 5KB. Bug lp:891738 """ # Set up a 'large' image of 5KB expected_swift_size = FIVE_KB expected_swift_contents = "*" * expected_swift_size expected_checksum = hashlib.md5(expected_swift_contents).hexdigest() expected_image_id = str(uuid.uuid4()) loc = 'swift+https://%s:key@localhost:8080/glance/%s' expected_location = loc % (self.swift_store_user, expected_image_id) image_swift = six.StringIO(expected_swift_contents) global SWIFT_PUT_OBJECT_CALLS SWIFT_PUT_OBJECT_CALLS = 0 # Temporarily set Swift MAX_SWIFT_OBJECT_SIZE to 1KB and add our image, # explicitly setting the image_length to 0 self.config(swift_store_container='glance') self.store = Store() orig_max_size = self.store.large_object_size orig_temp_size = self.store.large_object_chunk_size global MAX_SWIFT_OBJECT_SIZE orig_max_swift_object_size = MAX_SWIFT_OBJECT_SIZE try: MAX_SWIFT_OBJECT_SIZE = 1024 self.store.large_object_size = 1024 self.store.large_object_chunk_size = 1024 location, size, checksum, _ = self.store.add(expected_image_id, image_swift, 0) finally: self.store.large_object_chunk_size = orig_temp_size self.store.large_object_size = orig_max_size MAX_SWIFT_OBJECT_SIZE = orig_max_swift_object_size self.assertEqual(expected_location, location) self.assertEqual(expected_swift_size, size) self.assertEqual(expected_checksum, checksum) # Expecting 7 calls to put_object -- 5 chunks, a zero chunk which is # then deleted, and the manifest. Note the difference with above # where the image_size is specified in advance (there's no zero chunk # in that case). self.assertEqual(SWIFT_PUT_OBJECT_CALLS, 7) loc = get_location_from_uri(expected_location) (new_image_swift, new_image_size) = self.store.get(loc) new_image_contents = ''.join([chunk for chunk in new_image_swift]) new_image_swift_size = len(new_image_contents) self.assertEqual(expected_swift_contents, new_image_contents) self.assertEqual(expected_swift_size, new_image_swift_size) def test_add_already_existing(self): """ Tests that adding an image with an existing identifier raises an appropriate exception """ image_swift = six.StringIO("nevergonnamakeit") self.assertRaises(exception.Duplicate, self.store.add, FAKE_UUID, image_swift, 0) def test_add_saves_and_reraises_and_not_uses_wildcard_raise(self): image_id = str(uuid.uuid4()) swift_size = self.store.large_object_size = 1024 swift_contents = "*" * swift_size connection = mock.Mock() def fake_delete_chunk(connection, container, chunks): try: raise Exception() except Exception: pass image_swift = six.StringIO(swift_contents) connection.put_object.side_effect = exception.ClientConnectionError self.store._delete_stale_chunks = fake_delete_chunk self.assertRaises(exception.ClientConnectionError, self.store.add, image_id, image_swift, swift_size, connection) def _option_required(self, key): conf = self.getConfig() conf[key] = None try: self.config(**conf) self.store = Store() return self.store.add == self.store.add_disabled except Exception: return False return False def test_no_user(self): """ Tests that options without user disables the add method """ self.assertTrue(self._option_required('swift_store_user')) def test_no_key(self): """ Tests that options without key disables the add method """ self.assertTrue(self._option_required('swift_store_key')) def test_no_auth_address(self): """ Tests that options without auth address disables the add method """ self.assertTrue(self._option_required('swift_store_auth_address')) def test_delete(self): """ Test we can delete an existing image in the swift store """ uri = "swift://%s:key@authurl/glance/%s" % ( self.swift_store_user, FAKE_UUID) loc = get_location_from_uri(uri) self.store.delete(loc) self.assertRaises(exception.NotFound, self.store.get, loc) def test_delete_non_existing(self): """ Test that trying to delete a swift that doesn't exist raises an error """ loc = get_location_from_uri("swift://%s:key@authurl/glance/noexist" % ( self.swift_store_user)) self.assertRaises(exception.NotFound, self.store.delete, loc) def test_read_acl_public(self): """ Test that we can set a public read acl. """ self.config(swift_store_multi_tenant=True) context = glance.context.RequestContext() store = Store(context) uri = "swift+http://storeurl/glance/%s" % FAKE_UUID loc = get_location_from_uri(uri) store.set_acls(loc, public=True) container_headers = swiftclient.client.head_container('x', 'y', 'glance') self.assertEqual(container_headers['X-Container-Read'], ".r:*,.rlistings") def test_read_acl_tenants(self): """ Test that we can set read acl for tenants. """ self.config(swift_store_multi_tenant=True) context = glance.context.RequestContext() store = Store(context) uri = "swift+http://storeurl/glance/%s" % FAKE_UUID loc = get_location_from_uri(uri) read_tenants = ['matt', 'mark'] store.set_acls(loc, read_tenants=read_tenants) container_headers = swiftclient.client.head_container('x', 'y', 'glance') self.assertEqual(container_headers['X-Container-Read'], 'matt:*,mark:*') def test_write_acls(self): """ Test that we can set write acl for tenants. """ self.config(swift_store_multi_tenant=True) context = glance.context.RequestContext() store = Store(context) uri = "swift+http://storeurl/glance/%s" % FAKE_UUID loc = get_location_from_uri(uri) read_tenants = ['frank', 'jim'] store.set_acls(loc, write_tenants=read_tenants) container_headers = swiftclient.client.head_container('x', 'y', 'glance') self.assertEqual(container_headers['X-Container-Write'], 'frank:*,jim:*') class TestStoreAuthV1(base.StoreClearingUnitTest, SwiftTests): def getConfig(self): conf = SWIFT_CONF.copy() conf['swift_store_auth_version'] = '1' conf['swift_store_user'] = 'user' return conf def setUp(self): """Establish a clean test environment""" conf = self.getConfig() self.config(**conf) super(TestStoreAuthV1, self).setUp() self.stubs = stubout.StubOutForTesting() stub_out_swiftclient(self.stubs, conf['swift_store_auth_version']) self.store = Store() self.addCleanup(self.stubs.UnsetAll) class TestStoreAuthV2(TestStoreAuthV1): def getConfig(self): conf = super(TestStoreAuthV2, self).getConfig() conf['swift_store_user'] = 'tenant:user' conf['swift_store_auth_version'] = '2' return conf def test_v2_with_no_tenant(self): conf = self.getConfig() conf['swift_store_user'] = 'failme' uri = "swift://%s:key@auth_address/glance/%s" % ( conf['swift_store_user'], FAKE_UUID) loc = get_location_from_uri(uri) self.assertRaises(exception.BadStoreUri, self.store.get, loc) def test_v2_multi_tenant_location(self): conf = self.getConfig() conf['swift_store_multi_tenant'] = True uri = "swift://auth_address/glance/%s" % (FAKE_UUID) loc = get_location_from_uri(uri) self.assertEqual('swift', loc.store_name) class FakeConnection(object): def __init__(self, authurl, user, key, retries=5, preauthurl=None, preauthtoken=None, snet=False, starting_backoff=1, tenant_name=None, os_options={}, auth_version="1", insecure=False, ssl_compression=True): self.authurl = authurl self.user = user self.key = key self.preauthurl = preauthurl self.preauthtoken = preauthtoken self.snet = snet self.tenant_name = tenant_name self.os_options = os_options self.auth_version = auth_version self.insecure = insecure class TestSingleTenantStoreConnections(base.IsolatedUnitTest): def setUp(self): super(TestSingleTenantStoreConnections, self).setUp() self.stubs.Set(swiftclient, 'Connection', FakeConnection) self.store = glance.store.swift.SingleTenantStore() specs = {'scheme': 'swift', 'auth_or_store_url': 'example.com/v2/', 'user': 'tenant:user', 'key': 'abcdefg', 'container': 'cont', 'obj': 'object'} self.location = glance.store.swift.StoreLocation(specs) def test_basic_connection(self): connection = self.store.get_connection(self.location) self.assertEqual(connection.authurl, 'https://example.com/v2/') self.assertEqual(connection.auth_version, '2') self.assertEqual(connection.user, 'user') self.assertEqual(connection.tenant_name, 'tenant') self.assertEqual(connection.key, 'abcdefg') self.assertFalse(connection.snet) self.assertIsNone(connection.preauthurl) self.assertIsNone(connection.preauthtoken) self.assertFalse(connection.insecure) self.assertEqual(connection.os_options, {'service_type': 'object-store', 'endpoint_type': 'publicURL'}) def test_connection_with_no_trailing_slash(self): self.location.auth_or_store_url = 'example.com/v2' connection = self.store.get_connection(self.location) self.assertEqual(connection.authurl, 'https://example.com/v2/') def test_connection_insecure(self): self.config(swift_store_auth_insecure=True) self.store.configure() connection = self.store.get_connection(self.location) self.assertTrue(connection.insecure) def test_connection_with_auth_v1(self): self.config(swift_store_auth_version='1') self.store.configure() self.location.user = 'auth_v1_user' connection = self.store.get_connection(self.location) self.assertEqual(connection.auth_version, '1') self.assertEqual(connection.user, 'auth_v1_user') self.assertIsNone(connection.tenant_name) def test_connection_invalid_user(self): self.store.configure() self.location.user = 'invalid:format:user' self.assertRaises(exception.BadStoreUri, self.store.get_connection, self.location) def test_connection_missing_user(self): self.store.configure() self.location.user = None self.assertRaises(exception.BadStoreUri, self.store.get_connection, self.location) def test_connection_with_region(self): self.config(swift_store_region='Sahara') self.store.configure() connection = self.store.get_connection(self.location) self.assertEqual(connection.os_options, {'region_name': 'Sahara', 'service_type': 'object-store', 'endpoint_type': 'publicURL'}) def test_connection_with_service_type(self): self.config(swift_store_service_type='shoe-store') self.store.configure() connection = self.store.get_connection(self.location) self.assertEqual(connection.os_options, {'service_type': 'shoe-store', 'endpoint_type': 'publicURL'}) def test_connection_with_endpoint_type(self): self.config(swift_store_endpoint_type='internalURL') self.store.configure() connection = self.store.get_connection(self.location) self.assertEqual(connection.os_options, {'service_type': 'object-store', 'endpoint_type': 'internalURL'}) def test_connection_with_snet(self): self.config(swift_enable_snet=True) self.store.configure() connection = self.store.get_connection(self.location) self.assertTrue(connection.snet) class TestMultiTenantStoreConnections(base.IsolatedUnitTest): def setUp(self): super(TestMultiTenantStoreConnections, self).setUp() self.stubs.Set(swiftclient, 'Connection', FakeConnection) self.context = glance.context.RequestContext( user='user', tenant='tenant', auth_tok='0123') self.store = glance.store.swift.MultiTenantStore(self.context) specs = {'scheme': 'swift', 'auth_or_store_url': 'example.com', 'container': 'cont', 'obj': 'object'} self.location = glance.store.swift.StoreLocation(specs) def test_basic_connection(self): self.store.configure() connection = self.store.get_connection(self.location) self.assertIsNone(connection.authurl) self.assertEqual(connection.auth_version, '2') self.assertEqual(connection.user, 'user') self.assertEqual(connection.tenant_name, 'tenant') self.assertIsNone(connection.key) self.assertFalse(connection.snet) self.assertEqual(connection.preauthurl, 'https://example.com') self.assertEqual(connection.preauthtoken, '0123') self.assertEqual(connection.os_options, {}) def test_connection_with_snet(self): self.config(swift_enable_snet=True) self.store.configure() connection = self.store.get_connection(self.location) self.assertTrue(connection.snet) class FakeGetEndpoint(object): def __init__(self, response): self.response = response def __call__(self, service_catalog, service_type=None, endpoint_region=None, endpoint_type=None): self.service_type = service_type self.endpoint_region = endpoint_region self.endpoint_type = endpoint_type return self.response class TestCreatingLocations(base.IsolatedUnitTest): def test_single_tenant_location(self): self.config(swift_store_auth_address='example.com/v2', swift_store_container='container', swift_store_user='tenant:user', swift_store_key='auth_key') store = glance.store.swift.SingleTenantStore() location = store.create_location('image-id') self.assertEqual(location.scheme, 'swift+https') self.assertEqual(location.swift_url, 'https://example.com/v2') self.assertEqual(location.container, 'container') self.assertEqual(location.obj, 'image-id') self.assertEqual(location.user, 'tenant:user') self.assertEqual(location.key, 'auth_key') def test_single_tenant_location_http(self): self.config(swift_store_auth_address='http://example.com/v2', swift_store_container='container', swift_store_user='tenant:user', swift_store_key='auth_key') store = glance.store.swift.SingleTenantStore() location = store.create_location('image-id') self.assertEqual(location.scheme, 'swift+http') self.assertEqual(location.swift_url, 'http://example.com/v2') def test_multi_tenant_location(self): self.config(swift_store_container='container') fake_get_endpoint = FakeGetEndpoint('https://some_endpoint') self.stubs.Set(glance.common.auth, 'get_endpoint', fake_get_endpoint) context = glance.context.RequestContext( user='user', tenant='tenant', auth_tok='123', service_catalog={}) store = glance.store.swift.MultiTenantStore(context) location = store.create_location('image-id') self.assertEqual(location.scheme, 'swift+https') self.assertEqual(location.swift_url, 'https://some_endpoint') self.assertEqual(location.container, 'container_image-id') self.assertEqual(location.obj, 'image-id') self.assertIsNone(location.user) self.assertIsNone(location.key) self.assertEqual(fake_get_endpoint.service_type, 'object-store') def test_multi_tenant_location_http(self): fake_get_endpoint = FakeGetEndpoint('http://some_endpoint') self.stubs.Set(glance.common.auth, 'get_endpoint', fake_get_endpoint) context = glance.context.RequestContext( user='user', tenant='tenant', auth_tok='123', service_catalog={}) store = glance.store.swift.MultiTenantStore(context) location = store.create_location('image-id') self.assertEqual(location.scheme, 'swift+http') self.assertEqual(location.swift_url, 'http://some_endpoint') def test_multi_tenant_location_with_region(self): self.config(swift_store_region='WestCarolina') fake_get_endpoint = FakeGetEndpoint('https://some_endpoint') self.stubs.Set(glance.common.auth, 'get_endpoint', fake_get_endpoint) context = glance.context.RequestContext( user='user', tenant='tenant', auth_tok='123', service_catalog={}) glance.store.swift.MultiTenantStore(context) self.assertEqual(fake_get_endpoint.endpoint_region, 'WestCarolina') def test_multi_tenant_location_custom_service_type(self): self.config(swift_store_service_type='toy-store') fake_get_endpoint = FakeGetEndpoint('https://some_endpoint') self.stubs.Set(glance.common.auth, 'get_endpoint', fake_get_endpoint) context = glance.context.RequestContext( user='user', tenant='tenant', auth_tok='123', service_catalog={}) glance.store.swift.MultiTenantStore(context) self.assertEqual(fake_get_endpoint.service_type, 'toy-store') def test_multi_tenant_location_custom_endpoint_type(self): self.config(swift_store_endpoint_type='InternalURL') fake_get_endpoint = FakeGetEndpoint('https://some_endpoint') self.stubs.Set(glance.common.auth, 'get_endpoint', fake_get_endpoint) context = glance.context.RequestContext( user='user', tenant='tenant', auth_tok='123', service_catalog={}) glance.store.swift.MultiTenantStore(context) self.assertEqual(fake_get_endpoint.endpoint_type, 'InternalURL') class TestChunkReader(base.StoreClearingUnitTest): def test_read_all_data(self): """ Replicate what goes on in the Swift driver with the repeated creation of the ChunkReader object """ CHUNKSIZE = 100 checksum = hashlib.md5() data_file = tempfile.NamedTemporaryFile() data_file.write('*' * units.Ki) data_file.flush() infile = open(data_file.name, 'rb') bytes_read = 0 while True: cr = glance.store.swift.ChunkReader(infile, checksum, CHUNKSIZE) chunk = cr.read(CHUNKSIZE) bytes_read += len(chunk) if not chunk: break self.assertEqual(1024, bytes_read) data_file.close() glance-2014.1/glance/tests/unit/utils.py0000664000175400017540000001646012323736226021271 0ustar jenkinsjenkins00000000000000# Copyright 2012 OpenStack Foundation. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from oslo.config import cfg from glance.common import exception from glance.common import wsgi import glance.context import glance.db.simple.api as simple_db import glance.openstack.common.log as logging import glance.store CONF = cfg.CONF LOG = logging.getLogger(__name__) UUID1 = 'c80a1a6c-bd1f-41c5-90ee-81afedb1d58d' UUID2 = '971ec09a-8067-4bc8-a91f-ae3557f1c4c7' TENANT1 = '6838eb7b-6ded-434a-882c-b344c77fe8df' TENANT2 = '2c014f32-55eb-467d-8fcb-4bd706012f81' USER1 = '54492ba0-f4df-4e4e-be62-27f4d76b29cf' USER2 = '0b3b3006-cb76-4517-ae32-51397e22c754' USER3 = '2hss8dkl-d8jh-88yd-uhs9-879sdjsd8skd' BASE_URI = 'http://storeurl.com/container' def get_fake_request(path='', method='POST', is_admin=False, user=USER1, roles=['member'], tenant=TENANT1): req = wsgi.Request.blank(path) req.method = method kwargs = { 'user': user, 'tenant': tenant, 'roles': roles, 'is_admin': is_admin, } req.context = glance.context.RequestContext(**kwargs) return req def fake_get_size_from_backend(context, uri): return 1 class FakeDB(object): def __init__(self): self.reset() self.init_db() @staticmethod def init_db(): images = [ {'id': UUID1, 'owner': TENANT1, 'status': 'queued', 'locations': [{'url': '%s/%s' % (BASE_URI, UUID1), 'metadata': {}}]}, {'id': UUID2, 'owner': TENANT1, 'status': 'queued'}, ] [simple_db.image_create(None, image) for image in images] members = [ {'image_id': UUID1, 'member': TENANT1, 'can_share': True}, {'image_id': UUID1, 'member': TENANT2, 'can_share': False}, ] [simple_db.image_member_create(None, member) for member in members] simple_db.image_tag_set_all(None, UUID1, ['ping', 'pong']) @staticmethod def reset(): simple_db.reset() def __getattr__(self, key): return getattr(simple_db, key) class FakeStoreAPI(object): def __init__(self, store_metadata=None): self.data = { '%s/%s' % (BASE_URI, UUID1): ('XXX', 3), '%s/fake_location' % (BASE_URI): ('YYY', 3) } self.acls = {} if store_metadata is None: self.store_metadata = {} else: self.store_metadata = store_metadata def create_stores(self): pass def set_acls(self, context, uri, public=False, read_tenants=[], write_tenants=[]): self.acls[uri] = { 'public': public, 'read': read_tenants, 'write': write_tenants, } def get_from_backend(self, context, location): try: scheme = location[:location.find('/') - 1] if scheme == 'unknown': raise exception.UnknownScheme(scheme=scheme) return self.data[location] except KeyError: raise exception.NotFound() def safe_delete_from_backend(self, context, uri, id, **kwargs): try: del self.data[uri] except KeyError: pass def schedule_delayed_delete_from_backend(self, context, uri, id, **kwargs): pass def delete_image_from_backend(self, context, store_api, image_id, uri): if CONF.delayed_delete: self.schedule_delayed_delete_from_backend(context, uri, image_id) else: self.safe_delete_from_backend(context, uri, image_id) def get_size_from_backend(self, context, location): return self.get_from_backend(context, location)[1] def add_to_backend(self, context, scheme, image_id, data, size): store_max_size = 7 current_store_size = 2 for location in self.data.keys(): if image_id in location: raise exception.Duplicate() if not size: size = len(data.fd) if (current_store_size + size) > store_max_size: raise exception.StorageFull() if context.user == USER2: raise exception.Forbidden() if context.user == USER3: raise exception.StorageWriteDenied() self.data[image_id] = (data, size) checksum = 'Z' return (image_id, size, checksum, self.store_metadata) def check_location_metadata(self, val, key=''): glance.store.check_location_metadata(val) class FakePolicyEnforcer(object): def __init__(self, *_args, **kwargs): self.rules = {} def enforce(self, _ctxt, action, target=None, **kwargs): """Raise Forbidden if a rule for given action is set to false.""" if self.rules.get(action) is False: raise exception.Forbidden() def set_rules(self, rules): self.rules = rules class FakeNotifier(object): def __init__(self, *_args, **kwargs): self.log = [] def _notify(self, event_type, payload, level): log = {} log['notification_type'] = level log['event_type'] = event_type log['payload'] = payload self.log.append(log) def warn(self, event_type, payload): self._notify(event_type, payload, 'WARN') def info(self, event_type, payload): self._notify(event_type, payload, 'INFO') def error(self, event_type, payload): self._notify(event_type, payload, 'ERROR') def debug(self, event_type, payload): self._notify(event_type, payload, 'DEBUG') def critical(self, event_type, payload): self._notify(event_type, payload, 'CRITICAL') def get_logs(self): return self.log class FakeGateway(object): def __init__(self, image_factory=None, image_member_factory=None, image_repo=None, task_factory=None, task_repo=None): self.image_factory = image_factory self.image_member_factory = image_member_factory self.image_repo = image_repo self.task_factory = task_factory self.task_repo = task_repo def get_image_factory(self, context): return self.image_factory def get_image_member_factory(self, context): return self.image_member_factory def get_repo(self, context): return self.image_repo def get_task_factory(self, context): return self.task_factory def get_task_repo(self, context): return self.task_repo class FakeTask(object): def __init__(self, task_id, type=None, status=None): self.task_id = task_id self.type = type self.message = None self.input = None self._status = status self._executor = None def success(self, result): self.result = result self._status = 'success' def fail(self, message): self.message = message self._status = 'failure' glance-2014.1/glance/tests/unit/test_gridfs_store.py0000664000175400017540000000571312323736226023661 0ustar jenkinsjenkins00000000000000# Copyright 2013 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import six import stubout from glance.common import exception from glance.common import utils from glance.store.gridfs import Store from glance.tests.unit import base try: import gridfs import pymongo except ImportError: pymongo = None GRIDFS_CONF = {'verbose': True, 'debug': True, 'default_store': 'gridfs', 'mongodb_store_uri': 'mongodb://fake_store_uri', 'mongodb_store_db': 'fake_store_db'} def stub_out_gridfs(stubs): class FakeMongoClient(object): def __init__(self, *args, **kwargs): pass def __getitem__(self, key): return None class FakeGridFS(object): image_data = {} called_commands = [] def __init__(self, *args, **kwargs): pass def exists(self, image_id): self.called_commands.append('exists') return False def put(self, image_file, _id): self.called_commands.append('put') data = None while True: data = image_file.read(64) if data: self.image_data[_id] = \ self.image_data.setdefault(_id, '') + data else: break def delete(self, _id): self.called_commands.append('delete') if pymongo is not None: stubs.Set(pymongo, 'MongoClient', FakeMongoClient) stubs.Set(gridfs, 'GridFS', FakeGridFS) class TestStore(base.StoreClearingUnitTest): def setUp(self): """Establish a clean test environment""" self.config(**GRIDFS_CONF) super(TestStore, self).setUp() self.stubs = stubout.StubOutForTesting() stub_out_gridfs(self.stubs) self.store = Store() self.addCleanup(self.stubs.UnsetAll) def test_cleanup_when_add_image_exception(self): if pymongo is None: msg = 'GridFS store can not add images, skip test.' self.skipTest(msg) self.assertRaises(exception.ImageSizeLimitExceeded, self.store.add, 'fake_image_id', utils.LimitingReader(six.StringIO('xx'), 1), 2) self.assertEqual(self.store.fs.called_commands, ['exists', 'put', 'delete']) glance-2014.1/glance/tests/unit/test_rbd_store.py0000664000175400017540000001533212323736226023150 0ustar jenkinsjenkins00000000000000# Copyright 2013 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import mock import six from glance.common import exception from glance.common import utils from glance.openstack.common import units from glance.store.location import Location import glance.store.rbd as rbd_store from glance.store.rbd import StoreLocation from glance.tests.unit import base from glance.tests.unit.fake_rados import mock_rados from glance.tests.unit.fake_rados import mock_rbd class TestStore(base.StoreClearingUnitTest): def setUp(self): """Establish a clean test environment""" super(TestStore, self).setUp() self.stubs.Set(rbd_store, 'rados', mock_rados) self.stubs.Set(rbd_store, 'rbd', mock_rbd) self.store = rbd_store.Store() self.store.chunk_size = 2 self.called_commands_actual = [] self.called_commands_expected = [] self.store_specs = {'image': 'fake_image', 'snapshot': 'fake_snapshot'} self.location = StoreLocation(self.store_specs) # Provide enough data to get more than one chunk iteration. self.data_len = 3 * units.Ki self.data_iter = six.StringIO('*' * self.data_len) def test_add_w_image_size_zero(self): """Assert that correct size is returned even though 0 was provided.""" self.store.chunk_size = units.Ki with mock.patch.object(rbd_store.rbd.Image, 'resize') as resize: with mock.patch.object(rbd_store.rbd.Image, 'write') as write: ret = self.store.add('fake_image_id', self.data_iter, 0) resize.assert_called() write.assert_called() self.assertEqual(ret[1], self.data_len) def test_add_w_rbd_image_exception(self): def _fake_create_image(*args, **kwargs): self.called_commands_actual.append('create') return self.location def _fake_delete_image(*args, **kwargs): self.called_commands_actual.append('delete') def _fake_enter(*args, **kwargs): raise exception.NotFound("") self.stubs.Set(self.store, '_create_image', _fake_create_image) self.stubs.Set(self.store, '_delete_image', _fake_delete_image) self.stubs.Set(mock_rbd.Image, '__enter__', _fake_enter) self.assertRaises(exception.NotFound, self.store.add, 'fake_image_id', self.data_iter, self.data_len) self.called_commands_expected = ['create', 'delete'] def test_add_duplicate_image(self): def _fake_create_image(*args, **kwargs): self.called_commands_actual.append('create') raise mock_rbd.ImageExists() self.stubs.Set(self.store, '_create_image', _fake_create_image) self.assertRaises(exception.Duplicate, self.store.add, 'fake_image_id', self.data_iter, self.data_len) self.called_commands_expected = ['create'] def test_delete(self): def _fake_remove(*args, **kwargs): self.called_commands_actual.append('remove') self.stubs.Set(mock_rbd.RBD, 'remove', _fake_remove) self.store.delete(Location('test_rbd_store', StoreLocation, self.location.get_uri())) self.called_commands_expected = ['remove'] def test__delete_image(self): def _fake_remove(*args, **kwargs): self.called_commands_actual.append('remove') self.stubs.Set(mock_rbd.RBD, 'remove', _fake_remove) self.store._delete_image(self.location) self.called_commands_expected = ['remove'] def test__delete_image_w_snap(self): def _fake_unprotect_snap(*args, **kwargs): self.called_commands_actual.append('unprotect_snap') def _fake_remove_snap(*args, **kwargs): self.called_commands_actual.append('remove_snap') def _fake_remove(*args, **kwargs): self.called_commands_actual.append('remove') self.stubs.Set(mock_rbd.RBD, 'remove', _fake_remove) self.stubs.Set(mock_rbd.Image, 'unprotect_snap', _fake_unprotect_snap) self.stubs.Set(mock_rbd.Image, 'remove_snap', _fake_remove_snap) self.store._delete_image(self.location, snapshot_name='snap') self.called_commands_expected = ['unprotect_snap', 'remove_snap', 'remove'] def test__delete_image_w_snap_exc_image_not_found(self): def _fake_unprotect_snap(*args, **kwargs): self.called_commands_actual.append('unprotect_snap') raise mock_rbd.ImageNotFound() self.stubs.Set(mock_rbd.Image, 'unprotect_snap', _fake_unprotect_snap) self.assertRaises(exception.NotFound, self.store._delete_image, self.location, snapshot_name='snap') self.called_commands_expected = ['unprotect_snap'] def test__delete_image_exc_image_not_found(self): def _fake_remove(*args, **kwargs): self.called_commands_actual.append('remove') raise mock_rbd.ImageNotFound() self.stubs.Set(mock_rbd.RBD, 'remove', _fake_remove) self.assertRaises(exception.NotFound, self.store._delete_image, self.location, snapshot_name='snap') self.called_commands_expected = ['remove'] def test_image_size_exceeded_exception(self): def _fake_write(*args, **kwargs): if 'write' not in self.called_commands_actual: self.called_commands_actual.append('write') raise exception.ImageSizeLimitExceeded def _fake_delete_image(*args, **kwargs): self.called_commands_actual.append('delete') self.stubs.Set(mock_rbd.Image, 'write', _fake_write) self.stubs.Set(self.store, '_delete_image', _fake_delete_image) data = utils.LimitingReader(self.data_iter, self.data_len) self.assertRaises(exception.ImageSizeLimitExceeded, self.store.add, 'fake_image_id', data, self.data_len + 1) self.called_commands_expected = ['write', 'delete'] def tearDown(self): self.assertEqual(self.called_commands_actual, self.called_commands_expected) super(TestStore, self).tearDown() glance-2014.1/glance/tests/unit/base.py0000664000175400017540000000624412323736226021042 0ustar jenkinsjenkins00000000000000# Copyright 2012 OpenStack Foundation. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import os import shutil import fixtures from oslo.config import cfg from glance.openstack.common import jsonutils from glance import store from glance.store import location from glance.store import sheepdog from glance.store import vmware_datastore from glance.tests import stubs from glance.tests import utils as test_utils CONF = cfg.CONF CONF.import_opt('filesystem_store_datadir', 'glance.store.filesystem') CONF.import_opt('connection', 'glance.openstack.common.db.sqlalchemy.session', group='database') class StoreClearingUnitTest(test_utils.BaseTestCase): def setUp(self): super(StoreClearingUnitTest, self).setUp() # Ensure stores + locations cleared location.SCHEME_TO_CLS_MAP = {} self._create_stores() self.addCleanup(setattr, location, 'SCHEME_TO_CLS_MAP', dict()) def _create_stores(self): """Create known stores. Mock out sheepdog's subprocess dependency on collie. """ self.stubs.Set(sheepdog.Store, 'configure_add', lambda x: None) self.stubs.Set(vmware_datastore.Store, 'configure', lambda x: None) self.stubs.Set(vmware_datastore.Store, 'configure_add', lambda x: None) store.create_stores() class IsolatedUnitTest(StoreClearingUnitTest): """ Unit test case that establishes a mock environment within a testing directory (in isolation) """ registry = None def setUp(self): super(IsolatedUnitTest, self).setUp() self.test_dir = self.useFixture(fixtures.TempDir()).path policy_file = self._copy_data_file('policy.json', self.test_dir) self.config(connection='sqlite://', group='database') self.config(verbose=False, debug=False, default_store='filesystem', filesystem_store_datadir=os.path.join(self.test_dir), policy_file=policy_file, lock_path=os.path.join(self.test_dir)) stubs.stub_out_registry_and_store_server(self.stubs, self.test_dir, registry=self.registry) def _copy_data_file(self, file_name, dst_dir): src_file_name = os.path.join('glance/tests/etc', file_name) shutil.copy(src_file_name, dst_dir) dst_file_name = os.path.join(dst_dir, file_name) return dst_file_name def set_policy_rules(self, rules): fap = open(CONF.policy_file, 'w') fap.write(jsonutils.dumps(rules)) fap.close() glance-2014.1/glance/tests/unit/test_schema.py0000664000175400017540000001346112323736226022426 0ustar jenkinsjenkins00000000000000# Copyright 2012 OpenStack Foundation. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from glance.common import exception import glance.schema from glance.tests import utils as test_utils class TestBasicSchema(test_utils.BaseTestCase): def setUp(self): super(TestBasicSchema, self).setUp() properties = { 'ham': {'type': 'string'}, 'eggs': {'type': 'string'}, } self.schema = glance.schema.Schema('basic', properties) def test_validate_passes(self): obj = {'ham': 'no', 'eggs': 'scrambled'} self.schema.validate(obj) # No exception raised def test_validate_fails_on_extra_properties(self): obj = {'ham': 'virginia', 'eggs': 'scrambled', 'bacon': 'crispy'} self.assertRaises(exception.InvalidObject, self.schema.validate, obj) def test_validate_fails_on_bad_type(self): obj = {'eggs': 2} self.assertRaises(exception.InvalidObject, self.schema.validate, obj) def test_filter_strips_extra_properties(self): obj = {'ham': 'virginia', 'eggs': 'scrambled', 'bacon': 'crispy'} filtered = self.schema.filter(obj) expected = {'ham': 'virginia', 'eggs': 'scrambled'} self.assertEqual(filtered, expected) def test_merge_properties(self): self.schema.merge_properties({'bacon': {'type': 'string'}}) expected = set(['ham', 'eggs', 'bacon']) actual = set(self.schema.raw()['properties'].keys()) self.assertEqual(actual, expected) def test_merge_conflicting_properties(self): conflicts = {'eggs': {'type': 'integer'}} self.assertRaises(exception.SchemaLoadError, self.schema.merge_properties, conflicts) def test_merge_conflicting_but_identical_properties(self): conflicts = {'ham': {'type': 'string'}} self.schema.merge_properties(conflicts) # no exception raised expected = set(['ham', 'eggs']) actual = set(self.schema.raw()['properties'].keys()) self.assertEqual(actual, expected) def test_raw_json_schema(self): expected = { 'name': 'basic', 'properties': { 'ham': {'type': 'string'}, 'eggs': {'type': 'string'}, }, 'additionalProperties': False, } self.assertEqual(self.schema.raw(), expected) class TestBasicSchemaLinks(test_utils.BaseTestCase): def setUp(self): super(TestBasicSchemaLinks, self).setUp() properties = { 'ham': {'type': 'string'}, 'eggs': {'type': 'string'}, } links = [ {'rel': 'up', 'href': '/menu'}, ] self.schema = glance.schema.Schema('basic', properties, links) def test_raw_json_schema(self): expected = { 'name': 'basic', 'properties': { 'ham': {'type': 'string'}, 'eggs': {'type': 'string'}, }, 'links': [ {'rel': 'up', 'href': '/menu'}, ], 'additionalProperties': False, } self.assertEqual(self.schema.raw(), expected) class TestPermissiveSchema(test_utils.BaseTestCase): def setUp(self): super(TestPermissiveSchema, self).setUp() properties = { 'ham': {'type': 'string'}, 'eggs': {'type': 'string'}, } self.schema = glance.schema.PermissiveSchema('permissive', properties) def test_validate_with_additional_properties_allowed(self): obj = {'ham': 'virginia', 'eggs': 'scrambled', 'bacon': 'crispy'} self.schema.validate(obj) # No exception raised def test_validate_rejects_non_string_extra_properties(self): obj = {'ham': 'virginia', 'eggs': 'scrambled', 'grits': 1000} self.assertRaises(exception.InvalidObject, self.schema.validate, obj) def test_filter_passes_extra_properties(self): obj = {'ham': 'virginia', 'eggs': 'scrambled', 'bacon': 'crispy'} filtered = self.schema.filter(obj) self.assertEqual(filtered, obj) def test_raw_json_schema(self): expected = { 'name': 'permissive', 'properties': { 'ham': {'type': 'string'}, 'eggs': {'type': 'string'}, }, 'additionalProperties': {'type': 'string'}, } self.assertEqual(self.schema.raw(), expected) class TestCollectionSchema(test_utils.BaseTestCase): def test_raw_json_schema(self): item_properties = {'cheese': {'type': 'string'}} item_schema = glance.schema.Schema('mouse', item_properties) collection_schema = glance.schema.CollectionSchema('mice', item_schema) expected = { 'name': 'mice', 'properties': { 'mice': { 'type': 'array', 'items': item_schema.raw(), }, 'first': {'type': 'string'}, 'next': {'type': 'string'}, 'schema': {'type': 'string'}, }, 'links': [ {'rel': 'first', 'href': '{first}'}, {'rel': 'next', 'href': '{next}'}, {'rel': 'describedby', 'href': '{schema}'}, ], } self.assertEqual(collection_schema.raw(), expected) glance-2014.1/glance/tests/unit/test_policy.py0000664000175400017540000004663312323736230022467 0ustar jenkinsjenkins00000000000000# Copyright 2012 OpenStack Foundation # Copyright 2013 IBM Corp. # 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 os.path import mock import oslo.config.cfg import glance.api.policy from glance.common import exception import glance.context from glance.tests.unit import base import glance.tests.unit.utils as unit_test_utils from glance.tests import utils as test_utils UUID1 = 'c80a1a6c-bd1f-41c5-90ee-81afedb1d58d' class ImageRepoStub(object): def get(self, *args, **kwargs): return 'image_from_get' def save(self, *args, **kwargs): return 'image_from_save' def add(self, *args, **kwargs): return 'image_from_add' def list(self, *args, **kwargs): return ['image_from_list_0', 'image_from_list_1'] class ImageStub(object): def __init__(self, image_id, visibility='private'): self.image_id = image_id self.visibility = visibility self.status = 'active' def delete(self): self.status = 'deleted' class ImageFactoryStub(object): def new_image(self, image_id=None, name=None, visibility='private', min_disk=0, min_ram=0, protected=False, owner=None, disk_format=None, container_format=None, extra_properties=None, tags=None, **other_args): self.visibility = visibility return 'new_image' class MemberRepoStub(object): def add(self, image_member): image_member.output = 'member_repo_add' def get(self, *args, **kwargs): return 'member_repo_get' def save(self, image_member): image_member.output = 'member_repo_save' def list(self, *args, **kwargs): return 'member_repo_list' def remove(self, image_member): image_member.output = 'member_repo_remove' class ImageMembershipStub(object): def __init__(self, output=None): self.output = output class TaskRepoStub(object): def get_task_and_details(self, *args, **kwargs): return 'task_from_get', 'task_details_from_get' def add(self, *args, **kwargs): return 'task_from_add' def list_tasks(self, *args, **kwargs): return ['task_from_list_0', 'task_from_list_1'] class TaskStub(object): def __init__(self, task_id): self.task_id = task_id self.status = 'pending' def run(self, executor): self.status = 'processing' class TaskFactoryStub(object): def new_task(self, *args): return 'new_task' class TestPolicyEnforcer(base.IsolatedUnitTest): def test_policy_file_default_rules_default_location(self): enforcer = glance.api.policy.Enforcer() context = glance.context.RequestContext(roles=[]) enforcer.enforce(context, 'get_image', {}) def test_policy_file_custom_rules_default_location(self): rules = {"get_image": '!'} self.set_policy_rules(rules) enforcer = glance.api.policy.Enforcer() context = glance.context.RequestContext(roles=[]) self.assertRaises(exception.Forbidden, enforcer.enforce, context, 'get_image', {}) def test_policy_file_custom_location(self): self.config(policy_file=os.path.join(self.test_dir, 'gobble.gobble')) rules = {"get_image": '!'} self.set_policy_rules(rules) enforcer = glance.api.policy.Enforcer() context = glance.context.RequestContext(roles=[]) self.assertRaises(exception.Forbidden, enforcer.enforce, context, 'get_image', {}) def test_policy_file_check(self): self.config(policy_file=os.path.join(self.test_dir, 'gobble.gobble')) rules = {"get_image": '!'} self.set_policy_rules(rules) enforcer = glance.api.policy.Enforcer() context = glance.context.RequestContext(roles=[]) self.assertEqual(enforcer.check(context, 'get_image', {}), False) class TestPolicyEnforcerNoFile(base.IsolatedUnitTest): def test_policy_file_specified_but_not_found(self): """Missing defined policy file should result in a default ruleset""" self.config(policy_file='gobble.gobble') enforcer = glance.api.policy.Enforcer() context = glance.context.RequestContext(roles=[]) enforcer.enforce(context, 'get_image', {}) self.assertRaises(exception.Forbidden, enforcer.enforce, context, 'manage_image_cache', {}) admin_context = glance.context.RequestContext(roles=['admin']) enforcer.enforce(admin_context, 'manage_image_cache', {}) def test_policy_file_default_not_found(self): """Missing default policy file should result in a default ruleset""" def fake_find_file(self, name): return None self.stubs.Set(oslo.config.cfg.ConfigOpts, 'find_file', fake_find_file) enforcer = glance.api.policy.Enforcer() context = glance.context.RequestContext(roles=[]) enforcer.enforce(context, 'get_image', {}) self.assertRaises(exception.Forbidden, enforcer.enforce, context, 'manage_image_cache', {}) admin_context = glance.context.RequestContext(roles=['admin']) enforcer.enforce(admin_context, 'manage_image_cache', {}) class TestImagePolicy(test_utils.BaseTestCase): def setUp(self): self.image_stub = ImageStub(UUID1) self.image_repo_stub = ImageRepoStub() self.image_factory_stub = ImageFactoryStub() self.policy = mock.Mock() self.policy.enforce = mock.Mock() super(TestImagePolicy, self).setUp() def test_publicize_image_not_allowed(self): self.policy.enforce.side_effect = exception.Forbidden image = glance.api.policy.ImageProxy(self.image_stub, {}, self.policy) self.assertRaises(exception.Forbidden, setattr, image, 'visibility', 'public') self.assertEqual(image.visibility, 'private') self.policy.enforce.assert_called_once_with({}, "publicize_image", {}) def test_publicize_image_allowed(self): image = glance.api.policy.ImageProxy(self.image_stub, {}, self.policy) image.visibility = 'public' self.assertEqual(image.visibility, 'public') self.policy.enforce.assert_called_once_with({}, "publicize_image", {}) def test_delete_image_not_allowed(self): self.policy.enforce.side_effect = exception.Forbidden image = glance.api.policy.ImageProxy(self.image_stub, {}, self.policy) self.assertRaises(exception.Forbidden, image.delete) self.assertEqual(image.status, 'active') self.policy.enforce.assert_called_once_with({}, "delete_image", {}) def test_delete_image_allowed(self): image = glance.api.policy.ImageProxy(self.image_stub, {}, self.policy) image.delete() self.assertEqual(image.status, 'deleted') self.policy.enforce.assert_called_once_with({}, "delete_image", {}) def test_get_image_not_allowed(self): self.policy.enforce.side_effect = exception.Forbidden image_repo = glance.api.policy.ImageRepoProxy(self.image_repo_stub, {}, self.policy) self.assertRaises(exception.Forbidden, image_repo.get, UUID1) self.policy.enforce.assert_called_once_with({}, "get_image", {}) def test_get_image_allowed(self): image_repo = glance.api.policy.ImageRepoProxy(self.image_repo_stub, {}, self.policy) output = image_repo.get(UUID1) self.assertIsInstance(output, glance.api.policy.ImageProxy) self.assertEqual(output.image, 'image_from_get') self.policy.enforce.assert_called_once_with({}, "get_image", {}) def test_get_images_not_allowed(self): self.policy.enforce.side_effect = exception.Forbidden image_repo = glance.api.policy.ImageRepoProxy(self.image_repo_stub, {}, self.policy) self.assertRaises(exception.Forbidden, image_repo.list) self.policy.enforce.assert_called_once_with({}, "get_images", {}) def test_get_images_allowed(self): image_repo = glance.api.policy.ImageRepoProxy(self.image_repo_stub, {}, self.policy) images = image_repo.list() for i, image in enumerate(images): self.assertIsInstance(image, glance.api.policy.ImageProxy) self.assertEqual(image.image, 'image_from_list_%d' % i) self.policy.enforce.assert_called_once_with({}, "get_images", {}) def test_modify_image_not_allowed(self): self.policy.enforce.side_effect = exception.Forbidden image_repo = glance.api.policy.ImageRepoProxy(self.image_repo_stub, {}, self.policy) image = glance.api.policy.ImageProxy(self.image_stub, {}, self.policy) self.assertRaises(exception.Forbidden, image_repo.save, image) self.policy.enforce.assert_called_once_with({}, "modify_image", {}) def test_modify_image_allowed(self): image_repo = glance.api.policy.ImageRepoProxy(self.image_repo_stub, {}, self.policy) image = glance.api.policy.ImageProxy(self.image_stub, {}, self.policy) image_repo.save(image) self.policy.enforce.assert_called_once_with({}, "modify_image", {}) def test_add_image_not_allowed(self): self.policy.enforce.side_effect = exception.Forbidden image_repo = glance.api.policy.ImageRepoProxy(self.image_repo_stub, {}, self.policy) image = glance.api.policy.ImageProxy(self.image_stub, {}, self.policy) self.assertRaises(exception.Forbidden, image_repo.add, image) self.policy.enforce.assert_called_once_with({}, "add_image", {}) def test_add_image_allowed(self): image_repo = glance.api.policy.ImageRepoProxy(self.image_repo_stub, {}, self.policy) image = glance.api.policy.ImageProxy(self.image_stub, {}, self.policy) image_repo.add(image) self.policy.enforce.assert_called_once_with({}, "add_image", {}) def test_new_image_visibility(self): self.policy.enforce.side_effect = exception.Forbidden image_factory = glance.api.policy.ImageFactoryProxy( self.image_factory_stub, {}, self.policy) self.assertRaises(exception.Forbidden, image_factory.new_image, visibility='public') self.policy.enforce.assert_called_once_with({}, "publicize_image", {}) def test_new_image_visibility_public_allowed(self): image_factory = glance.api.policy.ImageFactoryProxy( self.image_factory_stub, {}, self.policy) image_factory.new_image(visibility='public') self.policy.enforce.assert_called_once_with({}, "publicize_image", {}) def test_image_get_data(self): self.policy.enforce.side_effect = exception.Forbidden image = glance.api.policy.ImageProxy(self.image_stub, {}, self.policy) self.assertRaises(exception.Forbidden, image.get_data) self.policy.enforce.assert_called_once_with({}, "download_image", {}) def test_image_set_data(self): self.policy.enforce.side_effect = exception.Forbidden image = glance.api.policy.ImageProxy(self.image_stub, {}, self.policy) self.assertRaises(exception.Forbidden, image.set_data) self.policy.enforce.assert_called_once_with({}, "upload_image", {}) class TestMemberPolicy(test_utils.BaseTestCase): def setUp(self): self.policy = mock.Mock() self.policy.enforce = mock.Mock() self.member_repo = glance.api.policy.ImageMemberRepoProxy( MemberRepoStub(), {}, self.policy) super(TestMemberPolicy, self).setUp() def test_add_member_not_allowed(self): self.policy.enforce.side_effect = exception.Forbidden self.assertRaises(exception.Forbidden, self.member_repo.add, '') self.policy.enforce.assert_called_once_with({}, "add_member", {}) def test_add_member_allowed(self): image_member = ImageMembershipStub() self.member_repo.add(image_member) self.assertEqual(image_member.output, 'member_repo_add') self.policy.enforce.assert_called_once_with({}, "add_member", {}) def test_get_member_not_allowed(self): self.policy.enforce.side_effect = exception.Forbidden self.assertRaises(exception.Forbidden, self.member_repo.get, '') self.policy.enforce.assert_called_once_with({}, "get_member", {}) def test_get_member_allowed(self): output = self.member_repo.get('') self.assertEqual(output, 'member_repo_get') self.policy.enforce.assert_called_once_with({}, "get_member", {}) def test_modify_member_not_allowed(self): self.policy.enforce.side_effect = exception.Forbidden self.assertRaises(exception.Forbidden, self.member_repo.save, '') self.policy.enforce.assert_called_once_with({}, "modify_member", {}) def test_modify_member_allowed(self): image_member = ImageMembershipStub() self.member_repo.save(image_member) self.assertEqual(image_member.output, 'member_repo_save') self.policy.enforce.assert_called_once_with({}, "modify_member", {}) def test_get_members_not_allowed(self): self.policy.enforce.side_effect = exception.Forbidden self.assertRaises(exception.Forbidden, self.member_repo.list, '') self.policy.enforce.assert_called_once_with({}, "get_members", {}) def test_get_members_allowed(self): output = self.member_repo.list('') self.assertEqual(output, 'member_repo_list') self.policy.enforce.assert_called_once_with({}, "get_members", {}) def test_delete_member_not_allowed(self): self.policy.enforce.side_effect = exception.Forbidden self.assertRaises(exception.Forbidden, self.member_repo.remove, '') self.policy.enforce.assert_called_once_with({}, "delete_member", {}) def test_delete_member_allowed(self): image_member = ImageMembershipStub() self.member_repo.remove(image_member) self.assertEqual(image_member.output, 'member_repo_remove') self.policy.enforce.assert_called_once_with({}, "delete_member", {}) class TestTaskPolicy(test_utils.BaseTestCase): def setUp(self): self.task_stub = TaskStub(UUID1) self.task_repo_stub = TaskRepoStub() self.task_factory_stub = TaskFactoryStub() self.policy = unit_test_utils.FakePolicyEnforcer() super(TestTaskPolicy, self).setUp() def test_get_task_not_allowed(self): rules = {"get_task": False} self.policy.set_rules(rules) task_repo = glance.api.policy.TaskRepoProxy( self.task_repo_stub, {}, self.policy ) self.assertRaises(exception.Forbidden, task_repo.get_task_and_details, UUID1) def test_get_task_allowed(self): rules = {"get_task": True} self.policy.set_rules(rules) task_repo = glance.api.policy.TaskRepoProxy( self.task_repo_stub, {}, self.policy ) task, task_details = task_repo.get_task_and_details(UUID1) self.assertIsInstance(task, glance.api.policy.TaskProxy) self.assertEqual(task.task, 'task_from_get') def test_get_tasks_not_allowed(self): rules = {"get_tasks": False} self.policy.set_rules(rules) task_repo = glance.api.policy.TaskRepoProxy( self.task_repo_stub, {}, self.policy ) self.assertRaises(exception.Forbidden, task_repo.list_tasks) def test_get_tasks_allowed(self): rules = {"get_task": True} self.policy.set_rules(rules) task_repo = glance.api.policy.TaskRepoProxy( self.task_repo_stub, {}, self.policy ) tasks = task_repo.list_tasks() for i, task in enumerate(tasks): self.assertIsInstance(task, glance.api.policy.TaskProxy) self.assertEqual(task.task, 'task_from_list_%d' % i) def test_add_task_not_allowed(self): rules = {"add_task": False} self.policy.set_rules(rules) task_repo = glance.api.policy.TaskRepoProxy( self.task_repo_stub, {}, self.policy ) task = glance.api.policy.TaskProxy(self.task_stub, {}, self.policy) self.assertRaises(exception.Forbidden, task_repo.add, task) def test_add_task_allowed(self): rules = {"add_task": True} self.policy.set_rules(rules) task_repo = glance.api.policy.TaskRepoProxy( self.task_repo_stub, {}, self.policy ) task = glance.api.policy.TaskProxy(self.task_stub, {}, self.policy) task_repo.add(task) class TestContextPolicyEnforcer(base.IsolatedUnitTest): def _do_test_policy_influence_context_admin(self, policy_admin_role, context_role, context_is_admin, admin_expected): self.config(policy_file=os.path.join(self.test_dir, 'gobble.gobble')) rules = {'context_is_admin': 'role:%s' % policy_admin_role} self.set_policy_rules(rules) enforcer = glance.api.policy.Enforcer() context = glance.context.RequestContext(roles=[context_role], is_admin=context_is_admin, policy_enforcer=enforcer) self.assertEqual(context.is_admin, admin_expected) def test_context_admin_policy_admin(self): self._do_test_policy_influence_context_admin('test_admin', 'test_admin', True, True) def test_context_nonadmin_policy_admin(self): self._do_test_policy_influence_context_admin('test_admin', 'test_admin', False, True) def test_context_admin_policy_nonadmin(self): self._do_test_policy_influence_context_admin('test_admin', 'demo', True, True) def test_context_nonadmin_policy_nonadmin(self): self._do_test_policy_influence_context_admin('test_admin', 'demo', False, False) glance-2014.1/glance/tests/unit/test_sheepdog_store.py0000664000175400017540000000406512323736226024200 0ustar jenkinsjenkins00000000000000# Copyright 2013 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import six import stubout from glance.common import exception from glance.common import utils from glance.openstack.common import processutils import glance.store.sheepdog from glance.store.sheepdog import Store from glance.tests.unit import base SHEEPDOG_CONF = {'verbose': True, 'debug': True, 'default_store': 'sheepdog'} class TestStore(base.StoreClearingUnitTest): def setUp(self): """Establish a clean test environment""" def _fake_execute(*cmd, **kwargs): pass self.config(**SHEEPDOG_CONF) super(TestStore, self).setUp() self.stubs = stubout.StubOutForTesting() self.stubs.Set(processutils, 'execute', _fake_execute) self.store = Store() self.addCleanup(self.stubs.UnsetAll) def test_cleanup_when_add_image_exception(self): called_commands = [] def _fake_run_command(self, command, data, *params): called_commands.append(command) self.stubs.Set(glance.store.sheepdog.SheepdogImage, '_run_command', _fake_run_command) self.assertRaises(exception.ImageSizeLimitExceeded, self.store.add, 'fake_image_id', utils.LimitingReader(six.StringIO('xx'), 1), 2) self.assertEqual([['list', '-r'], ['create'], ['delete']], called_commands) glance-2014.1/glance/tests/unit/v2/0000775000175400017540000000000012323736427020102 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/tests/unit/v2/test_image_tags_resource.py0000664000175400017540000000575012323736226025526 0ustar jenkinsjenkins00000000000000# Copyright 2012 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import webob import glance.api.v2.image_tags from glance.tests.unit import base import glance.tests.unit.utils as unit_test_utils import glance.tests.utils as test_utils class TestImageTagsController(base.IsolatedUnitTest): def setUp(self): super(TestImageTagsController, self).setUp() self.db = unit_test_utils.FakeDB() self.controller = glance.api.v2.image_tags.Controller(self.db) def test_create_tag(self): request = unit_test_utils.get_fake_request() self.controller.update(request, unit_test_utils.UUID1, 'dink') context = request.context tags = self.db.image_tag_get_all(context, unit_test_utils.UUID1) self.assertEqual(1, len([tag for tag in tags if tag == 'dink'])) def test_create_too_many_tags(self): self.config(image_tag_quota=0) request = unit_test_utils.get_fake_request() self.assertRaises(webob.exc.HTTPRequestEntityTooLarge, self.controller.update, request, unit_test_utils.UUID1, 'dink') def test_create_duplicate_tag_ignored(self): request = unit_test_utils.get_fake_request() self.controller.update(request, unit_test_utils.UUID1, 'dink') self.controller.update(request, unit_test_utils.UUID1, 'dink') context = request.context tags = self.db.image_tag_get_all(context, unit_test_utils.UUID1) self.assertEqual(1, len([tag for tag in tags if tag == 'dink'])) def test_delete_tag(self): request = unit_test_utils.get_fake_request() self.controller.delete(request, unit_test_utils.UUID1, 'ping') def test_delete_tag_not_found(self): request = unit_test_utils.get_fake_request() self.assertRaises(webob.exc.HTTPNotFound, self.controller.delete, request, unit_test_utils.UUID1, 'what') class TestImagesSerializer(test_utils.BaseTestCase): def setUp(self): super(TestImagesSerializer, self).setUp() self.serializer = glance.api.v2.image_tags.ResponseSerializer() def test_create_tag(self): response = webob.Response() self.serializer.update(response, None) self.assertEqual(204, response.status_int) def test_delete_tag(self): response = webob.Response() self.serializer.delete(response, None) self.assertEqual(204, response.status_int) glance-2014.1/glance/tests/unit/v2/test_schemas_resource.py0000664000175400017540000000374312323736226025051 0ustar jenkinsjenkins00000000000000# Copyright 2012 OpenStack Foundation. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import glance.api.v2.schemas import glance.tests.unit.utils as unit_test_utils import glance.tests.utils as test_utils class TestSchemasController(test_utils.BaseTestCase): def setUp(self): super(TestSchemasController, self).setUp() self.controller = glance.api.v2.schemas.Controller() def test_image(self): req = unit_test_utils.get_fake_request() output = self.controller.image(req) self.assertEqual(output['name'], 'image') expected = set(['status', 'name', 'tags', 'checksum', 'created_at', 'disk_format', 'updated_at', 'visibility', 'self', 'file', 'container_format', 'schema', 'id', 'size', 'direct_url', 'min_ram', 'min_disk', 'protected', 'locations', 'owner', 'virtual_size']) self.assertEqual(set(output['properties'].keys()), expected) def test_images(self): req = unit_test_utils.get_fake_request() output = self.controller.images(req) self.assertEqual(output['name'], 'images') expected = set(['images', 'schema', 'first', 'next']) self.assertEqual(set(output['properties'].keys()), expected) expected = set(['{schema}', '{first}', '{next}']) actual = set([link['href'] for link in output['links']]) self.assertEqual(actual, expected) glance-2014.1/glance/tests/unit/v2/test_images_resource.py0000664000175400017540000042316612323736226024700 0ustar jenkinsjenkins00000000000000# Copyright 2012 OpenStack Foundation. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import datetime import uuid from oslo.config import cfg import testtools import webob import glance.api.v2.images from glance.common import exception from glance.openstack.common import jsonutils import glance.schema import glance.store from glance.tests.unit import base import glance.tests.unit.utils as unit_test_utils import glance.tests.utils as test_utils DATETIME = datetime.datetime(2012, 5, 16, 15, 27, 36, 325355) ISOTIME = '2012-05-16T15:27:36Z' CONF = cfg.CONF BASE_URI = unit_test_utils.BASE_URI UUID1 = 'c80a1a6c-bd1f-41c5-90ee-81afedb1d58d' UUID2 = 'a85abd86-55b3-4d5b-b0b4-5d0a6e6042fc' UUID3 = '971ec09a-8067-4bc8-a91f-ae3557f1c4c7' UUID4 = '6bbe7cc2-eae7-4c0f-b50d-a7160b0c6a86' TENANT1 = '6838eb7b-6ded-434a-882c-b344c77fe8df' TENANT2 = '2c014f32-55eb-467d-8fcb-4bd706012f81' TENANT3 = '5a3e60e8-cfa9-4a9e-a90a-62b42cea92b8' TENANT4 = 'c6c87f25-8a94-47ed-8c83-053c25f42df4' CHKSUM = '93264c3edf5972c9f1cb309543d38a5c' CHKSUM1 = '43254c3edf6972c9f1cb309543d38a8c' def _db_fixture(id, **kwargs): obj = { 'id': id, 'name': None, 'is_public': False, 'properties': {}, 'checksum': None, 'owner': None, 'status': 'queued', 'tags': [], 'size': None, 'virtual_size': None, 'locations': [], 'protected': False, 'disk_format': None, 'container_format': None, 'deleted': False, 'min_ram': None, 'min_disk': None, } obj.update(kwargs) return obj def _domain_fixture(id, **kwargs): properties = { 'image_id': id, 'name': None, 'visibility': 'private', 'checksum': None, 'owner': None, 'status': 'queued', 'size': None, 'virtual_size': None, 'locations': [], 'protected': False, 'disk_format': None, 'container_format': None, 'min_ram': None, 'min_disk': None, 'tags': [], } properties.update(kwargs) return glance.domain.Image(**properties) def _db_image_member_fixture(image_id, member_id, **kwargs): obj = { 'image_id': image_id, 'member': member_id, } obj.update(kwargs) return obj class TestImagesController(base.IsolatedUnitTest): def setUp(self): super(TestImagesController, self).setUp() self.db = unit_test_utils.FakeDB() self.policy = unit_test_utils.FakePolicyEnforcer() self.notifier = unit_test_utils.FakeNotifier() self.store = unit_test_utils.FakeStoreAPI() for i in range(1, 4): self.store.data['%s/fake_location_%i' % (BASE_URI, i)] = ('Z', 1) self._create_images() self._create_image_members() self.controller = glance.api.v2.images.ImagesController(self.db, self.policy, self.notifier, self.store) glance.store.create_stores() def _create_images(self): self.db.reset() self.images = [ _db_fixture(UUID1, owner=TENANT1, checksum=CHKSUM, name='1', size=256, virtual_size=1024, is_public=True, locations=[{'url': '%s/%s' % (BASE_URI, UUID1), 'metadata': {}}], disk_format='raw', container_format='bare', status='active'), _db_fixture(UUID2, owner=TENANT1, checksum=CHKSUM1, name='2', size=512, virtual_size=2048, is_public=True, disk_format='raw', container_format='bare', status='active', tags=['redhat', '64bit', 'power'], properties={'hypervisor_type': 'kvm', 'foo': 'bar', 'bar': 'foo'}), _db_fixture(UUID3, owner=TENANT3, checksum=CHKSUM1, name='3', size=512, virtual_size=2048, is_public=True, tags=['windows', '64bit', 'x86']), _db_fixture(UUID4, owner=TENANT4, name='4', size=1024, virtual_size=3072), ] [self.db.image_create(None, image) for image in self.images] self.db.image_tag_set_all(None, UUID1, ['ping', 'pong']) def _create_image_members(self): self.image_members = [ _db_image_member_fixture(UUID4, TENANT2), _db_image_member_fixture(UUID4, TENANT3, status='accepted'), ] [self.db.image_member_create(None, image_member) for image_member in self.image_members] def test_index(self): self.config(limit_param_default=1, api_limit_max=3) request = unit_test_utils.get_fake_request() output = self.controller.index(request) self.assertEqual(1, len(output['images'])) actual = set([image.image_id for image in output['images']]) expected = set([UUID3]) self.assertEqual(actual, expected) def test_index_member_status_accepted(self): self.config(limit_param_default=5, api_limit_max=5) request = unit_test_utils.get_fake_request(tenant=TENANT2) output = self.controller.index(request) self.assertEqual(3, len(output['images'])) actual = set([image.image_id for image in output['images']]) expected = set([UUID1, UUID2, UUID3]) # can see only the public image self.assertEqual(actual, expected) request = unit_test_utils.get_fake_request(tenant=TENANT3) output = self.controller.index(request) self.assertEqual(4, len(output['images'])) actual = set([image.image_id for image in output['images']]) expected = set([UUID1, UUID2, UUID3, UUID4]) self.assertEqual(actual, expected) def test_index_admin(self): request = unit_test_utils.get_fake_request(is_admin=True) output = self.controller.index(request) self.assertEqual(4, len(output['images'])) def test_index_admin_deleted_images_hidden(self): request = unit_test_utils.get_fake_request(is_admin=True) self.controller.delete(request, UUID1) output = self.controller.index(request) self.assertEqual(3, len(output['images'])) actual = set([image.image_id for image in output['images']]) expected = set([UUID2, UUID3, UUID4]) self.assertEqual(actual, expected) def test_index_return_parameters(self): self.config(limit_param_default=1, api_limit_max=3) request = unit_test_utils.get_fake_request() output = self.controller.index(request, marker=UUID3, limit=1, sort_key='created_at', sort_dir='desc') self.assertEqual(1, len(output['images'])) actual = set([image.image_id for image in output['images']]) expected = set([UUID2]) self.assertEqual(actual, expected) self.assertEqual(UUID2, output['next_marker']) def test_index_next_marker(self): self.config(limit_param_default=1, api_limit_max=3) request = unit_test_utils.get_fake_request() output = self.controller.index(request, marker=UUID3, limit=2) self.assertEqual(2, len(output['images'])) actual = set([image.image_id for image in output['images']]) expected = set([UUID2, UUID1]) self.assertEqual(actual, expected) self.assertEqual(UUID1, output['next_marker']) def test_index_no_next_marker(self): self.config(limit_param_default=1, api_limit_max=3) request = unit_test_utils.get_fake_request() output = self.controller.index(request, marker=UUID1, limit=2) self.assertEqual(0, len(output['images'])) actual = set([image.image_id for image in output['images']]) expected = set([]) self.assertEqual(actual, expected) self.assertTrue('next_marker' not in output) def test_index_with_id_filter(self): request = unit_test_utils.get_fake_request('/images?id=%s' % UUID1) output = self.controller.index(request, filters={'id': UUID1}) self.assertEqual(1, len(output['images'])) actual = set([image.image_id for image in output['images']]) expected = set([UUID1]) self.assertEqual(actual, expected) def test_index_with_checksum_filter_single_image(self): req = unit_test_utils.get_fake_request('/images?checksum=%s' % CHKSUM) output = self.controller.index(req, filters={'checksum': CHKSUM}) self.assertEqual(1, len(output['images'])) actual = list([image.image_id for image in output['images']]) expected = [UUID1] self.assertEqual(actual, expected) def test_index_with_checksum_filter_multiple_images(self): req = unit_test_utils.get_fake_request('/images?checksum=%s' % CHKSUM1) output = self.controller.index(req, filters={'checksum': CHKSUM1}) self.assertEqual(2, len(output['images'])) actual = list([image.image_id for image in output['images']]) expected = [UUID3, UUID2] self.assertEqual(actual, expected) def test_index_with_non_existent_checksum(self): req = unit_test_utils.get_fake_request('/images?checksum=236231827') output = self.controller.index(req, filters={'checksum': '236231827'}) self.assertEqual(0, len(output['images'])) def test_index_size_max_filter(self): request = unit_test_utils.get_fake_request('/images?size_max=512') output = self.controller.index(request, filters={'size_max': 512}) self.assertEqual(3, len(output['images'])) actual = set([image.image_id for image in output['images']]) expected = set([UUID1, UUID2, UUID3]) self.assertEqual(actual, expected) def test_index_size_min_filter(self): request = unit_test_utils.get_fake_request('/images?size_min=512') output = self.controller.index(request, filters={'size_min': 512}) self.assertEqual(2, len(output['images'])) actual = set([image.image_id for image in output['images']]) expected = set([UUID2, UUID3]) self.assertEqual(actual, expected) def test_index_size_range_filter(self): path = '/images?size_min=512&size_max=512' request = unit_test_utils.get_fake_request(path) output = self.controller.index(request, filters={'size_min': 512, 'size_max': 512}) self.assertEqual(2, len(output['images'])) actual = set([image.image_id for image in output['images']]) expected = set([UUID2, UUID3]) self.assertEqual(actual, expected) def test_index_virtual_size_max_filter(self): ref = '/images?virtual_size_max=2048' request = unit_test_utils.get_fake_request(ref) output = self.controller.index(request, filters={'virtual_size_max': 2048}) self.assertEqual(3, len(output['images'])) actual = set([image.image_id for image in output['images']]) expected = set([UUID1, UUID2, UUID3]) self.assertEqual(actual, expected) def test_index_virtual_size_min_filter(self): ref = '/images?virtual_size_min=2048' request = unit_test_utils.get_fake_request(ref) output = self.controller.index(request, filters={'virtual_size_min': 2048}) self.assertEqual(2, len(output['images'])) actual = set([image.image_id for image in output['images']]) expected = set([UUID2, UUID3]) self.assertEqual(actual, expected) def test_index_virtual_size_range_filter(self): path = '/images?virtual_size_min=512&virtual_size_max=2048' request = unit_test_utils.get_fake_request(path) output = self.controller.index(request, filters={'virtual_size_min': 2048, 'virtual_size_max': 2048}) self.assertEqual(2, len(output['images'])) actual = set([image.image_id for image in output['images']]) expected = set([UUID2, UUID3]) self.assertEqual(actual, expected) def test_index_with_invalid_max_range_filter_value(self): request = unit_test_utils.get_fake_request('/images?size_max=blah') self.assertRaises(webob.exc.HTTPBadRequest, self.controller.index, request, filters={'size_max': 'blah'}) def test_index_with_filters_return_many(self): path = '/images?status=queued' request = unit_test_utils.get_fake_request(path) output = self.controller.index(request, filters={'status': 'queued'}) self.assertEqual(1, len(output['images'])) actual = set([image.image_id for image in output['images']]) expected = set([UUID3]) self.assertEqual(actual, expected) def test_index_with_nonexistent_name_filter(self): request = unit_test_utils.get_fake_request('/images?name=%s' % 'blah') images = self.controller.index(request, filters={'name': 'blah'})['images'] self.assertEqual(0, len(images)) def test_index_with_non_default_is_public_filter(self): image = _db_fixture(str(uuid.uuid4()), is_public=False, owner=TENANT3) self.db.image_create(None, image) path = '/images?visibility=private' request = unit_test_utils.get_fake_request(path, is_admin=True) output = self.controller.index(request, filters={'visibility': 'private'}) self.assertEqual(2, len(output['images'])) def test_index_with_many_filters(self): url = '/images?status=queued&name=3' request = unit_test_utils.get_fake_request(url) output = self.controller.index(request, filters={ 'status': 'queued', 'name': '3', }) self.assertEqual(1, len(output['images'])) actual = set([image.image_id for image in output['images']]) expected = set([UUID3]) self.assertEqual(actual, expected) def test_index_with_marker(self): self.config(limit_param_default=1, api_limit_max=3) path = '/images' request = unit_test_utils.get_fake_request(path) output = self.controller.index(request, marker=UUID3) actual = set([image.image_id for image in output['images']]) self.assertEqual(1, len(actual)) self.assertTrue(UUID2 in actual) def test_index_with_limit(self): path = '/images' limit = 2 request = unit_test_utils.get_fake_request(path) output = self.controller.index(request, limit=limit) actual = set([image.image_id for image in output['images']]) self.assertEqual(limit, len(actual)) self.assertTrue(UUID3 in actual) self.assertTrue(UUID2 in actual) def test_index_greater_than_limit_max(self): self.config(limit_param_default=1, api_limit_max=3) path = '/images' request = unit_test_utils.get_fake_request(path) output = self.controller.index(request, limit=4) actual = set([image.image_id for image in output['images']]) self.assertEqual(3, len(actual)) self.assertTrue(output['next_marker'] not in output) def test_index_default_limit(self): self.config(limit_param_default=1, api_limit_max=3) path = '/images' request = unit_test_utils.get_fake_request(path) output = self.controller.index(request) actual = set([image.image_id for image in output['images']]) self.assertEqual(1, len(actual)) def test_index_with_sort_dir(self): path = '/images' request = unit_test_utils.get_fake_request(path) output = self.controller.index(request, sort_dir='asc', limit=3) actual = [image.image_id for image in output['images']] self.assertEqual(3, len(actual)) self.assertEqual(UUID1, actual[0]) self.assertEqual(UUID2, actual[1]) self.assertEqual(UUID3, actual[2]) def test_index_with_sort_key(self): path = '/images' request = unit_test_utils.get_fake_request(path) output = self.controller.index(request, sort_key='created_at', limit=3) actual = [image.image_id for image in output['images']] self.assertEqual(3, len(actual)) self.assertEqual(UUID3, actual[0]) self.assertEqual(UUID2, actual[1]) self.assertEqual(UUID1, actual[2]) def test_index_with_marker_not_found(self): fake_uuid = str(uuid.uuid4()) path = '/images' request = unit_test_utils.get_fake_request(path) self.assertRaises(webob.exc.HTTPBadRequest, self.controller.index, request, marker=fake_uuid) def test_index_invalid_sort_key(self): path = '/images' request = unit_test_utils.get_fake_request(path) self.assertRaises(webob.exc.HTTPBadRequest, self.controller.index, request, sort_key='foo') def test_index_zero_images(self): self.db.reset() request = unit_test_utils.get_fake_request() output = self.controller.index(request) self.assertEqual([], output['images']) def test_index_with_tags(self): path = '/images?tag=64bit' request = unit_test_utils.get_fake_request(path) output = self.controller.index(request, filters={'tags': ['64bit']}) actual = [image.tags for image in output['images']] self.assertEqual(2, len(actual)) self.assertTrue('64bit' in actual[0]) self.assertTrue('64bit' in actual[1]) def test_index_with_multi_tags(self): path = '/images?tag=power&tag=64bit' request = unit_test_utils.get_fake_request(path) output = self.controller.index(request, filters={'tags': ['power', '64bit']}) actual = [image.tags for image in output['images']] self.assertEqual(1, len(actual)) self.assertTrue('64bit' in actual[0]) self.assertTrue('power' in actual[0]) def test_index_with_multi_tags_and_nonexistent(self): path = '/images?tag=power&tag=fake' request = unit_test_utils.get_fake_request(path) output = self.controller.index(request, filters={'tags': ['power', 'fake']}) actual = [image.tags for image in output['images']] self.assertEqual(0, len(actual)) def test_index_with_tags_and_properties(self): path = '/images?tag=64bit&hypervisor_type=kvm' request = unit_test_utils.get_fake_request(path) output = self.controller.index(request, filters={'tags': ['64bit'], 'hypervisor_type': 'kvm'}) tags = [image.tags for image in output['images']] properties = [image.extra_properties for image in output['images']] self.assertTrue(len(tags) == len(properties)) self.assertTrue('64bit' in tags[0]) self.assertEqual('kvm', properties[0]['hypervisor_type']) def test_index_with_multiple_properties(self): path = '/images?foo=bar&hypervisor_type=kvm' request = unit_test_utils.get_fake_request(path) output = self.controller.index(request, filters={'foo': 'bar', 'hypervisor_type': 'kvm'}) properties = [image.extra_properties for image in output['images']] self.assertEqual('kvm', properties[0]['hypervisor_type']) self.assertEqual('bar', properties[0]['foo']) def test_index_with_core_and_extra_property(self): path = '/images?disk_format=raw&foo=bar' request = unit_test_utils.get_fake_request(path) output = self.controller.index(request, filters={'foo': 'bar', 'disk_format': 'raw'}) properties = [image.extra_properties for image in output['images']] self.assertEqual(1, len(output['images'])) self.assertEqual('raw', output['images'][0].disk_format) self.assertEqual('bar', properties[0]['foo']) def test_index_with_nonexistent_properties(self): path = '/images?abc=xyz&pudding=banana' request = unit_test_utils.get_fake_request(path) output = self.controller.index(request, filters={'abc': 'xyz', 'pudding': 'banana'}) self.assertEqual(len(output['images']), 0) def test_index_with_non_existent_tags(self): path = '/images?tag=fake' request = unit_test_utils.get_fake_request(path) output = self.controller.index(request, filters={'tags': ['fake']}) actual = [image.tags for image in output['images']] self.assertEqual(0, len(actual)) def test_show(self): request = unit_test_utils.get_fake_request() output = self.controller.show(request, image_id=UUID2) self.assertEqual(UUID2, output.image_id) self.assertEqual('2', output.name) def test_show_deleted_properties(self): """Ensure that the api filters out deleted image properties.""" # get the image properties into the odd state image = { 'id': str(uuid.uuid4()), 'status': 'active', 'properties': {'poo': 'bear'}, } self.db.image_create(None, image) self.db.image_update(None, image['id'], {'properties': {'yin': 'yang'}}, purge_props=True) request = unit_test_utils.get_fake_request() output = self.controller.show(request, image['id']) self.assertEqual(output.extra_properties['yin'], 'yang') def test_show_non_existent(self): request = unit_test_utils.get_fake_request() image_id = str(uuid.uuid4()) self.assertRaises(webob.exc.HTTPNotFound, self.controller.show, request, image_id) def test_show_deleted_image_admin(self): request = unit_test_utils.get_fake_request(is_admin=True) self.controller.delete(request, UUID1) self.assertRaises(webob.exc.HTTPNotFound, self.controller.show, request, UUID1) def test_show_not_allowed(self): request = unit_test_utils.get_fake_request() self.assertEqual(request.context.tenant, TENANT1) self.assertRaises(webob.exc.HTTPNotFound, self.controller.show, request, UUID4) def test_create(self): request = unit_test_utils.get_fake_request() image = {'name': 'image-1'} output = self.controller.create(request, image=image, extra_properties={}, tags=[]) self.assertEqual('image-1', output.name) self.assertEqual({}, output.extra_properties) self.assertEqual(set([]), output.tags) self.assertEqual('private', output.visibility) output_logs = self.notifier.get_logs() self.assertEqual(len(output_logs), 1) output_log = output_logs[0] self.assertEqual(output_log['notification_type'], 'INFO') self.assertEqual(output_log['event_type'], 'image.create') self.assertEqual(output_log['payload']['name'], 'image-1') def test_create_with_properties(self): request = unit_test_utils.get_fake_request() image_properties = {'foo': 'bar'} image = {'name': 'image-1'} output = self.controller.create(request, image=image, extra_properties=image_properties, tags=[]) self.assertEqual('image-1', output.name) self.assertEqual(image_properties, output.extra_properties) self.assertEqual(set([]), output.tags) self.assertEqual('private', output.visibility) output_logs = self.notifier.get_logs() self.assertEqual(len(output_logs), 1) output_log = output_logs[0] self.assertEqual(output_log['notification_type'], 'INFO') self.assertEqual(output_log['event_type'], 'image.create') self.assertEqual(output_log['payload']['name'], 'image-1') def test_create_with_too_many_properties(self): self.config(image_property_quota=1) request = unit_test_utils.get_fake_request() image_properties = {'foo': 'bar', 'foo2': 'bar'} image = {'name': 'image-1'} self.assertRaises(webob.exc.HTTPRequestEntityTooLarge, self.controller.create, request, image=image, extra_properties=image_properties, tags=[]) def test_create_with_bad_min_disk_size(self): request = unit_test_utils.get_fake_request() image = {'min_disk': -42, 'name': 'image-1'} self.assertRaises(webob.exc.HTTPBadRequest, self.controller.create, request, image=image, extra_properties={}, tags=[]) def test_create_with_bad_min_ram_size(self): request = unit_test_utils.get_fake_request() image = {'min_ram': -42, 'name': 'image-1'} self.assertRaises(webob.exc.HTTPBadRequest, self.controller.create, request, image=image, extra_properties={}, tags=[]) def test_create_public_image_as_admin(self): request = unit_test_utils.get_fake_request() image = {'name': 'image-1', 'visibility': 'public'} output = self.controller.create(request, image=image, extra_properties={}, tags=[]) self.assertEqual('public', output.visibility) output_logs = self.notifier.get_logs() self.assertEqual(len(output_logs), 1) output_log = output_logs[0] self.assertEqual(output_log['notification_type'], 'INFO') self.assertEqual(output_log['event_type'], 'image.create') self.assertEqual(output_log['payload']['id'], output.image_id) def test_create_duplicate_tags(self): request = unit_test_utils.get_fake_request() tags = ['ping', 'ping'] output = self.controller.create(request, image={}, extra_properties={}, tags=tags) self.assertEqual(set(['ping']), output.tags) output_logs = self.notifier.get_logs() self.assertEqual(len(output_logs), 1) output_log = output_logs[0] self.assertEqual(output_log['notification_type'], 'INFO') self.assertEqual(output_log['event_type'], 'image.create') self.assertEqual(output_log['payload']['id'], output.image_id) def test_create_with_too_many_tags(self): self.config(image_tag_quota=1) request = unit_test_utils.get_fake_request() tags = ['ping', 'pong'] self.assertRaises(webob.exc.HTTPRequestEntityTooLarge, self.controller.create, request, image={}, extra_properties={}, tags=tags) def test_update_no_changes(self): request = unit_test_utils.get_fake_request() output = self.controller.update(request, UUID1, changes=[]) self.assertEqual(output.image_id, UUID1) self.assertEqual(output.created_at, output.updated_at) self.assertEqual(len(output.tags), 2) self.assertTrue('ping' in output.tags) self.assertTrue('pong' in output.tags) output_logs = self.notifier.get_logs() #NOTE(markwash): don't send a notification if nothing is updated self.assertTrue(len(output_logs) == 0) def test_update_with_bad_min_disk(self): request = unit_test_utils.get_fake_request() changes = [{'op': 'replace', 'path': ['min_disk'], 'value': -42}] self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update, request, UUID1, changes=changes) def test_update_with_bad_min_ram(self): request = unit_test_utils.get_fake_request() changes = [{'op': 'replace', 'path': ['min_ram'], 'value': -42}] self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update, request, UUID1, changes=changes) def test_update_image_doesnt_exist(self): request = unit_test_utils.get_fake_request() self.assertRaises(webob.exc.HTTPNotFound, self.controller.update, request, str(uuid.uuid4()), changes=[]) def test_update_deleted_image_admin(self): request = unit_test_utils.get_fake_request(is_admin=True) self.controller.delete(request, UUID1) self.assertRaises(webob.exc.HTTPNotFound, self.controller.update, request, UUID1, changes=[]) def test_update_replace_base_attribute(self): self.db.image_update(None, UUID1, {'properties': {'foo': 'bar'}}) request = unit_test_utils.get_fake_request() changes = [{'op': 'replace', 'path': ['name'], 'value': 'fedora'}] output = self.controller.update(request, UUID1, changes) self.assertEqual(output.image_id, UUID1) self.assertEqual(output.name, 'fedora') self.assertEqual(output.extra_properties, {'foo': 'bar'}) self.assertNotEqual(output.created_at, output.updated_at) def test_update_replace_tags(self): request = unit_test_utils.get_fake_request() changes = [ {'op': 'replace', 'path': ['tags'], 'value': ['king', 'kong']}, ] output = self.controller.update(request, UUID1, changes) self.assertEqual(output.image_id, UUID1) self.assertEqual(len(output.tags), 2) self.assertTrue('king' in output.tags) self.assertTrue('kong' in output.tags) self.assertNotEqual(output.created_at, output.updated_at) def test_update_replace_property(self): request = unit_test_utils.get_fake_request() properties = {'foo': 'bar', 'snitch': 'golden'} self.db.image_update(None, UUID1, {'properties': properties}) output = self.controller.show(request, UUID1) self.assertEqual(output.extra_properties['foo'], 'bar') self.assertEqual(output.extra_properties['snitch'], 'golden') changes = [ {'op': 'replace', 'path': ['foo'], 'value': 'baz'}, ] output = self.controller.update(request, UUID1, changes) self.assertEqual(output.image_id, UUID1) self.assertEqual(output.extra_properties['foo'], 'baz') self.assertEqual(output.extra_properties['snitch'], 'golden') self.assertNotEqual(output.created_at, output.updated_at) def test_update_add_too_many_properties(self): self.config(image_property_quota=1) request = unit_test_utils.get_fake_request() changes = [ {'op': 'add', 'path': ['foo'], 'value': 'baz'}, {'op': 'add', 'path': ['snitch'], 'value': 'golden'}, ] self.assertRaises(webob.exc.HTTPRequestEntityTooLarge, self.controller.update, request, UUID1, changes) def test_update_add_and_remove_too_many_properties(self): request = unit_test_utils.get_fake_request() changes = [ {'op': 'add', 'path': ['foo'], 'value': 'baz'}, {'op': 'add', 'path': ['snitch'], 'value': 'golden'}, ] self.controller.update(request, UUID1, changes) self.config(image_property_quota=1) # We must remove two properties to avoid being # over the limit of 1 property changes = [ {'op': 'remove', 'path': ['foo']}, {'op': 'add', 'path': ['fizz'], 'value': 'buzz'}, ] self.assertRaises(webob.exc.HTTPRequestEntityTooLarge, self.controller.update, request, UUID1, changes) def test_update_add_unlimited_properties(self): self.config(image_property_quota=-1) request = unit_test_utils.get_fake_request() output = self.controller.show(request, UUID1) changes = [{'op': 'add', 'path': ['foo'], 'value': 'bar'}] output = self.controller.update(request, UUID1, changes) self.assertEqual(output.image_id, UUID1) self.assertNotEqual(output.created_at, output.updated_at) def test_update_format_properties(self): statuses_for_immutability = ['active', 'saving', 'killed'] request = unit_test_utils.get_fake_request(is_admin=True) for status in statuses_for_immutability: image = { 'id': str(uuid.uuid4()), 'status': status, 'disk_format': 'ari', 'container_format': 'ari', } self.db.image_create(None, image) changes = [ {'op': 'replace', 'path': ['disk_format'], 'value': 'ami'}, ] self.assertRaises(webob.exc.HTTPForbidden, self.controller.update, request, image['id'], changes) changes = [ {'op': 'replace', 'path': ['container_format'], 'value': 'ami'}, ] self.assertRaises(webob.exc.HTTPForbidden, self.controller.update, request, image['id'], changes) self.db.image_update(None, image['id'], {'status': 'queued'}) changes = [ {'op': 'replace', 'path': ['disk_format'], 'value': 'raw'}, {'op': 'replace', 'path': ['container_format'], 'value': 'bare'}, ] resp = self.controller.update(request, image['id'], changes) self.assertEqual(resp.disk_format, 'raw') self.assertEqual(resp.container_format, 'bare') def test_update_remove_property_while_over_limit(self): """ Ensure that image properties can be removed. Image properties should be able to be removed as long as the image has fewer than the limited number of image properties after the transaction. """ request = unit_test_utils.get_fake_request() changes = [ {'op': 'add', 'path': ['foo'], 'value': 'baz'}, {'op': 'add', 'path': ['snitch'], 'value': 'golden'}, {'op': 'add', 'path': ['fizz'], 'value': 'buzz'}, ] self.controller.update(request, UUID1, changes) self.config(image_property_quota=1) # We must remove two properties to avoid being # over the limit of 1 property changes = [ {'op': 'remove', 'path': ['foo']}, {'op': 'remove', 'path': ['snitch']}, ] output = self.controller.update(request, UUID1, changes) self.assertEqual(output.image_id, UUID1) self.assertEqual(len(output.extra_properties), 1) self.assertEqual(output.extra_properties['fizz'], 'buzz') self.assertNotEqual(output.created_at, output.updated_at) def test_update_add_and_remove_property_under_limit(self): """ Ensure that image properties can be removed. Image properties should be able to be added and removed simultaneously as long as the image has fewer than the limited number of image properties after the transaction. """ request = unit_test_utils.get_fake_request() changes = [ {'op': 'add', 'path': ['foo'], 'value': 'baz'}, {'op': 'add', 'path': ['snitch'], 'value': 'golden'}, ] self.controller.update(request, UUID1, changes) self.config(image_property_quota=1) # We must remove two properties to avoid being # over the limit of 1 property changes = [ {'op': 'remove', 'path': ['foo']}, {'op': 'remove', 'path': ['snitch']}, {'op': 'add', 'path': ['fizz'], 'value': 'buzz'}, ] output = self.controller.update(request, UUID1, changes) self.assertEqual(output.image_id, UUID1) self.assertEqual(len(output.extra_properties), 1) self.assertEqual(output.extra_properties['fizz'], 'buzz') self.assertNotEqual(output.created_at, output.updated_at) def test_update_replace_missing_property(self): request = unit_test_utils.get_fake_request() changes = [ {'op': 'replace', 'path': 'foo', 'value': 'baz'}, ] self.assertRaises(webob.exc.HTTPConflict, self.controller.update, request, UUID1, changes) def test_prop_protection_with_create_and_permitted_role(self): enforcer = glance.api.policy.Enforcer() self.controller = glance.api.v2.images.ImagesController(self.db, enforcer, self.notifier, self.store) self.set_property_protections() request = unit_test_utils.get_fake_request(roles=['admin']) image = {'name': 'image-1'} created_image = self.controller.create(request, image=image, extra_properties={}, tags=[]) another_request = unit_test_utils.get_fake_request(roles=['member']) changes = [ {'op': 'add', 'path': ['x_owner_foo'], 'value': 'bar'}, ] output = self.controller.update(another_request, created_image.image_id, changes) self.assertEqual(output.extra_properties['x_owner_foo'], 'bar') def test_prop_protection_with_update_and_permitted_policy(self): self.set_property_protections(use_policies=True) enforcer = glance.api.policy.Enforcer() self.controller = glance.api.v2.images.ImagesController(self.db, enforcer, self.notifier, self.store) request = unit_test_utils.get_fake_request(roles=['spl_role']) image = {'name': 'image-1'} extra_props = {'spl_creator_policy': 'bar'} created_image = self.controller.create(request, image=image, extra_properties=extra_props, tags=[]) self.assertEqual(created_image.extra_properties['spl_creator_policy'], 'bar') another_request = unit_test_utils.get_fake_request(roles=['spl_role']) changes = [ {'op': 'replace', 'path': ['spl_creator_policy'], 'value': 'par'}, ] self.assertRaises(webob.exc.HTTPForbidden, self.controller.update, another_request, created_image.image_id, changes) another_request = unit_test_utils.get_fake_request(roles=['admin']) output = self.controller.update(another_request, created_image.image_id, changes) self.assertEqual(output.extra_properties['spl_creator_policy'], 'par') def test_prop_protection_with_create_with_patch_and_policy(self): self.set_property_protections(use_policies=True) enforcer = glance.api.policy.Enforcer() self.controller = glance.api.v2.images.ImagesController(self.db, enforcer, self.notifier, self.store) request = unit_test_utils.get_fake_request(roles=['spl_role', 'admin']) image = {'name': 'image-1'} extra_props = {'spl_default_policy': 'bar'} created_image = self.controller.create(request, image=image, extra_properties=extra_props, tags=[]) another_request = unit_test_utils.get_fake_request(roles=['fake_role']) changes = [ {'op': 'add', 'path': ['spl_creator_policy'], 'value': 'bar'}, ] self.assertRaises(webob.exc.HTTPForbidden, self.controller.update, another_request, created_image.image_id, changes) another_request = unit_test_utils.get_fake_request(roles=['spl_role']) output = self.controller.update(another_request, created_image.image_id, changes) self.assertEqual(output.extra_properties['spl_creator_policy'], 'bar') def test_prop_protection_with_create_and_unpermitted_role(self): enforcer = glance.api.policy.Enforcer() self.controller = glance.api.v2.images.ImagesController(self.db, enforcer, self.notifier, self.store) self.set_property_protections() request = unit_test_utils.get_fake_request(roles=['admin']) image = {'name': 'image-1'} created_image = self.controller.create(request, image=image, extra_properties={}, tags=[]) roles = ['fake_member'] another_request = unit_test_utils.get_fake_request(roles=roles) changes = [ {'op': 'add', 'path': ['x_owner_foo'], 'value': 'bar'}, ] self.assertRaises(webob.exc.HTTPForbidden, self.controller.update, another_request, created_image.image_id, changes) def test_prop_protection_with_show_and_permitted_role(self): enforcer = glance.api.policy.Enforcer() self.controller = glance.api.v2.images.ImagesController(self.db, enforcer, self.notifier, self.store) self.set_property_protections() request = unit_test_utils.get_fake_request(roles=['admin']) image = {'name': 'image-1'} extra_props = {'x_owner_foo': 'bar'} created_image = self.controller.create(request, image=image, extra_properties=extra_props, tags=[]) another_request = unit_test_utils.get_fake_request(roles=['member']) output = self.controller.show(another_request, created_image.image_id) self.assertEqual(output.extra_properties['x_owner_foo'], 'bar') def test_prop_protection_with_show_and_unpermitted_role(self): enforcer = glance.api.policy.Enforcer() self.controller = glance.api.v2.images.ImagesController(self.db, enforcer, self.notifier, self.store) self.set_property_protections() request = unit_test_utils.get_fake_request(roles=['member']) image = {'name': 'image-1'} extra_props = {'x_owner_foo': 'bar'} created_image = self.controller.create(request, image=image, extra_properties=extra_props, tags=[]) another_request = unit_test_utils.get_fake_request(roles=['fake_role']) output = self.controller.show(another_request, created_image.image_id) self.assertRaises(KeyError, output.extra_properties.__getitem__, 'x_owner_foo') def test_prop_protection_with_update_and_permitted_role(self): enforcer = glance.api.policy.Enforcer() self.controller = glance.api.v2.images.ImagesController(self.db, enforcer, self.notifier, self.store) self.set_property_protections() request = unit_test_utils.get_fake_request(roles=['admin']) image = {'name': 'image-1'} extra_props = {'x_owner_foo': 'bar'} created_image = self.controller.create(request, image=image, extra_properties=extra_props, tags=[]) another_request = unit_test_utils.get_fake_request(roles=['member']) changes = [ {'op': 'replace', 'path': ['x_owner_foo'], 'value': 'baz'}, ] output = self.controller.update(another_request, created_image.image_id, changes) self.assertEqual(output.extra_properties['x_owner_foo'], 'baz') def test_prop_protection_with_update_and_unpermitted_role(self): enforcer = glance.api.policy.Enforcer() self.controller = glance.api.v2.images.ImagesController(self.db, enforcer, self.notifier, self.store) self.set_property_protections() request = unit_test_utils.get_fake_request(roles=['admin']) image = {'name': 'image-1'} extra_props = {'x_owner_foo': 'bar'} created_image = self.controller.create(request, image=image, extra_properties=extra_props, tags=[]) another_request = unit_test_utils.get_fake_request(roles=['fake_role']) changes = [ {'op': 'replace', 'path': ['x_owner_foo'], 'value': 'baz'}, ] self.assertRaises(webob.exc.HTTPConflict, self.controller.update, another_request, created_image.image_id, changes) def test_prop_protection_with_delete_and_permitted_role(self): enforcer = glance.api.policy.Enforcer() self.controller = glance.api.v2.images.ImagesController(self.db, enforcer, self.notifier, self.store) self.set_property_protections() request = unit_test_utils.get_fake_request(roles=['admin']) image = {'name': 'image-1'} extra_props = {'x_owner_foo': 'bar'} created_image = self.controller.create(request, image=image, extra_properties=extra_props, tags=[]) another_request = unit_test_utils.get_fake_request(roles=['member']) changes = [ {'op': 'remove', 'path': ['x_owner_foo']} ] output = self.controller.update(another_request, created_image.image_id, changes) self.assertRaises(KeyError, output.extra_properties.__getitem__, 'x_owner_foo') def test_prop_protection_with_delete_and_unpermitted_role(self): enforcer = glance.api.policy.Enforcer() self.controller = glance.api.v2.images.ImagesController(self.db, enforcer, self.notifier, self.store) self.set_property_protections() request = unit_test_utils.get_fake_request(roles=['admin']) image = {'name': 'image-1'} extra_props = {'x_owner_foo': 'bar'} created_image = self.controller.create(request, image=image, extra_properties=extra_props, tags=[]) another_request = unit_test_utils.get_fake_request(roles=['fake_role']) changes = [ {'op': 'remove', 'path': ['x_owner_foo']} ] self.assertRaises(webob.exc.HTTPConflict, self.controller.update, another_request, created_image.image_id, changes) def test_create_non_protected_prop(self): """ Verify property marked with special char '@' is creatable by an unknown role """ self.set_property_protections() request = unit_test_utils.get_fake_request(roles=['admin']) image = {'name': 'image-1'} extra_props = {'x_all_permitted_1': '1'} created_image = self.controller.create(request, image=image, extra_properties=extra_props, tags=[]) self.assertEqual(created_image.extra_properties['x_all_permitted_1'], '1') another_request = unit_test_utils.get_fake_request(roles=['joe_soap']) extra_props = {'x_all_permitted_2': '2'} created_image = self.controller.create(another_request, image=image, extra_properties=extra_props, tags=[]) self.assertEqual(created_image.extra_properties['x_all_permitted_2'], '2') def test_read_non_protected_prop(self): """ Verify property marked with special char '@' is readable by an unknown role """ self.set_property_protections() request = unit_test_utils.get_fake_request(roles=['admin']) image = {'name': 'image-1'} extra_props = {'x_all_permitted': '1'} created_image = self.controller.create(request, image=image, extra_properties=extra_props, tags=[]) another_request = unit_test_utils.get_fake_request(roles=['joe_soap']) output = self.controller.show(another_request, created_image.image_id) self.assertEqual(output.extra_properties['x_all_permitted'], '1') def test_update_non_protected_prop(self): """ Verify property marked with special char '@' is updatable by an unknown role """ self.set_property_protections() request = unit_test_utils.get_fake_request(roles=['admin']) image = {'name': 'image-1'} extra_props = {'x_all_permitted': 'bar'} created_image = self.controller.create(request, image=image, extra_properties=extra_props, tags=[]) another_request = unit_test_utils.get_fake_request(roles=['joe_soap']) changes = [ {'op': 'replace', 'path': ['x_all_permitted'], 'value': 'baz'}, ] output = self.controller.update(another_request, created_image.image_id, changes) self.assertEqual(output.extra_properties['x_all_permitted'], 'baz') def test_delete_non_protected_prop(self): """ Verify property marked with special char '@' is deletable by an unknown role """ self.set_property_protections() request = unit_test_utils.get_fake_request(roles=['admin']) image = {'name': 'image-1'} extra_props = {'x_all_permitted': 'bar'} created_image = self.controller.create(request, image=image, extra_properties=extra_props, tags=[]) another_request = unit_test_utils.get_fake_request(roles=['member']) changes = [ {'op': 'remove', 'path': ['x_all_permitted']} ] output = self.controller.update(another_request, created_image.image_id, changes) self.assertRaises(KeyError, output.extra_properties.__getitem__, 'x_all_permitted') def test_create_locked_down_protected_prop(self): """ Verify a property protected by special char '!' is creatable by no one """ self.set_property_protections() request = unit_test_utils.get_fake_request(roles=['admin']) image = {'name': 'image-1'} created_image = self.controller.create(request, image=image, extra_properties={}, tags=[]) roles = ['fake_member'] another_request = unit_test_utils.get_fake_request(roles=roles) changes = [ {'op': 'add', 'path': ['x_none_permitted'], 'value': 'bar'}, ] self.assertRaises(webob.exc.HTTPForbidden, self.controller.update, another_request, created_image.image_id, changes) def test_read_locked_down_protected_prop(self): """ Verify a property protected by special char '!' is readable by no one """ self.set_property_protections() request = unit_test_utils.get_fake_request(roles=['member']) image = {'name': 'image-1'} extra_props = {'x_none_read': 'bar'} created_image = self.controller.create(request, image=image, extra_properties=extra_props, tags=[]) another_request = unit_test_utils.get_fake_request(roles=['fake_role']) output = self.controller.show(another_request, created_image.image_id) self.assertRaises(KeyError, output.extra_properties.__getitem__, 'x_none_read') def test_update_locked_down_protected_prop(self): """ Verify a property protected by special char '!' is updatable by no one """ self.set_property_protections() request = unit_test_utils.get_fake_request(roles=['admin']) image = {'name': 'image-1'} extra_props = {'x_none_update': 'bar'} created_image = self.controller.create(request, image=image, extra_properties=extra_props, tags=[]) another_request = unit_test_utils.get_fake_request(roles=['fake_role']) changes = [ {'op': 'replace', 'path': ['x_none_update'], 'value': 'baz'}, ] self.assertRaises(webob.exc.HTTPConflict, self.controller.update, another_request, created_image.image_id, changes) def test_delete_locked_down_protected_prop(self): """ Verify a property protected by special char '!' is deletable by no one """ self.set_property_protections() request = unit_test_utils.get_fake_request(roles=['admin']) image = {'name': 'image-1'} extra_props = {'x_none_delete': 'bar'} created_image = self.controller.create(request, image=image, extra_properties=extra_props, tags=[]) another_request = unit_test_utils.get_fake_request(roles=['fake_role']) changes = [ {'op': 'remove', 'path': ['x_none_delete']} ] self.assertRaises(webob.exc.HTTPConflict, self.controller.update, another_request, created_image.image_id, changes) def test_update_replace_locations(self): self.stubs.Set(glance.store, 'get_size_from_backend', unit_test_utils.fake_get_size_from_backend) request = unit_test_utils.get_fake_request() changes = [{'op': 'replace', 'path': ['locations'], 'value': []}] output = self.controller.update(request, UUID1, changes) self.assertEqual(output.image_id, UUID1) self.assertEqual(len(output.locations), 0) self.assertEqual(output.status, 'queued') self.assertIsNone(output.size) new_location = {'url': '%s/fake_location' % BASE_URI, 'metadata': {}} changes = [{'op': 'replace', 'path': ['locations'], 'value': [new_location]}] output = self.controller.update(request, UUID1, changes) self.assertEqual(output.image_id, UUID1) self.assertEqual(len(output.locations), 1) self.assertEqual(new_location, output.locations[0]) self.assertEqual(output.status, 'active') def test_update_replace_locations_non_empty(self): new_location = {'url': '%s/fake_location' % BASE_URI, 'metadata': {}} request = unit_test_utils.get_fake_request() changes = [{'op': 'replace', 'path': ['locations'], 'value': [new_location]}] self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update, request, UUID1, changes) def test_update_replace_locations_invalid(self): request = unit_test_utils.get_fake_request() changes = [{'op': 'replace', 'path': ['locations'], 'value': []}] output = self.controller.update(request, UUID1, changes) self.assertEqual(output.image_id, UUID1) self.assertEqual(len(output.locations), 0) self.assertEqual(output.status, 'queued') request = unit_test_utils.get_fake_request() changes = [{'op': 'replace', 'path': ['locations'], 'value': [{'url': 'unknow://foo', 'metadata': {}}]}] self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update, request, UUID1, changes) def test_update_replace_locations_status_exception(self): request = unit_test_utils.get_fake_request() changes = [{'op': 'replace', 'path': ['locations'], 'value': []}] output = self.controller.update(request, UUID2, changes) self.assertEqual(output.image_id, UUID2) self.assertEqual(len(output.locations), 0) self.assertEqual(output.status, 'queued') self.db.image_update(None, UUID2, {'disk_format': None}) new_location = {'url': '%s/fake_location' % BASE_URI, 'metadata': {}} changes = [{'op': 'replace', 'path': ['locations'], 'value': [new_location]}] self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update, request, UUID2, changes) def test_update_add_property(self): request = unit_test_utils.get_fake_request() changes = [ {'op': 'add', 'path': ['foo'], 'value': 'baz'}, {'op': 'add', 'path': ['snitch'], 'value': 'golden'}, ] output = self.controller.update(request, UUID1, changes) self.assertEqual(output.image_id, UUID1) self.assertEqual(output.extra_properties['foo'], 'baz') self.assertEqual(output.extra_properties['snitch'], 'golden') self.assertNotEqual(output.created_at, output.updated_at) def test_update_add_base_property(self): self.db.image_update(None, UUID1, {'properties': {'foo': 'bar'}}) request = unit_test_utils.get_fake_request() changes = [{'op': 'add', 'path': ['name'], 'value': 'fedora'}] self.assertRaises(webob.exc.HTTPConflict, self.controller.update, request, UUID1, changes) def test_update_add_property_already_present(self): request = unit_test_utils.get_fake_request() properties = {'foo': 'bar'} self.db.image_update(None, UUID1, {'properties': properties}) output = self.controller.show(request, UUID1) self.assertEqual(output.extra_properties['foo'], 'bar') changes = [ {'op': 'add', 'path': ['foo'], 'value': 'baz'}, ] self.assertRaises(webob.exc.HTTPConflict, self.controller.update, request, UUID1, changes) def test_update_add_locations(self): new_location = {'url': '%s/fake_location' % BASE_URI, 'metadata': {}} request = unit_test_utils.get_fake_request() changes = [{'op': 'add', 'path': ['locations', '-'], 'value': new_location}] output = self.controller.update(request, UUID1, changes) self.assertEqual(output.image_id, UUID1) self.assertEqual(len(output.locations), 2) self.assertEqual(new_location, output.locations[1]) def test_update_add_locations_insertion(self): new_location = {'url': '%s/fake_location' % BASE_URI, 'metadata': {}} request = unit_test_utils.get_fake_request() changes = [{'op': 'add', 'path': ['locations', '0'], 'value': new_location}] output = self.controller.update(request, UUID1, changes) self.assertEqual(output.image_id, UUID1) self.assertEqual(len(output.locations), 2) self.assertEqual(new_location, output.locations[0]) def test_update_add_locations_list(self): request = unit_test_utils.get_fake_request() changes = [{'op': 'add', 'path': ['locations', '-'], 'value': {'url': 'foo', 'metadata': {}}}] self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update, request, UUID1, changes) def test_update_add_locations_invalid(self): request = unit_test_utils.get_fake_request() changes = [{'op': 'add', 'path': ['locations', '-'], 'value': {'url': 'unknow://foo', 'metadata': {}}}] self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update, request, UUID1, changes) changes = [{'op': 'add', 'path': ['locations', None], 'value': {'url': 'unknow://foo', 'metadata': {}}}] self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update, request, UUID1, changes) def test_update_add_locations_status_exception(self): request = unit_test_utils.get_fake_request() changes = [{'op': 'replace', 'path': ['locations'], 'value': []}] output = self.controller.update(request, UUID2, changes) self.assertEqual(output.image_id, UUID2) self.assertEqual(len(output.locations), 0) self.assertEqual(output.status, 'queued') self.db.image_update(None, UUID2, {'disk_format': None}) new_location = {'url': '%s/fake_location' % BASE_URI, 'metadata': {}} changes = [{'op': 'add', 'path': ['locations', '-'], 'value': new_location}] self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update, request, UUID2, changes) def test_update_add_duplicate_locations(self): new_location = {'url': '%s/fake_location' % BASE_URI, 'metadata': {}} request = unit_test_utils.get_fake_request() changes = [{'op': 'add', 'path': ['locations', '-'], 'value': new_location}] output = self.controller.update(request, UUID1, changes) self.assertEqual(output.image_id, UUID1) self.assertEqual(len(output.locations), 2) self.assertEqual(new_location, output.locations[1]) self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update, request, UUID1, changes) def test_update_replace_duplicate_locations(self): request = unit_test_utils.get_fake_request() changes = [{'op': 'replace', 'path': ['locations'], 'value': []}] output = self.controller.update(request, UUID1, changes) self.assertEqual(output.image_id, UUID1) self.assertEqual(len(output.locations), 0) self.assertEqual(output.status, 'queued') new_location = {'url': '%s/fake_location' % BASE_URI, 'metadata': {}} changes = [{'op': 'replace', 'path': ['locations'], 'value': [new_location, new_location]}] self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update, request, UUID1, changes) def test_update_add_too_many_locations(self): self.config(image_location_quota=1) request = unit_test_utils.get_fake_request() changes = [ {'op': 'add', 'path': ['locations', '-'], 'value': {'url': '%s/fake_location_1' % BASE_URI, 'metadata': {}}}, {'op': 'add', 'path': ['locations', '-'], 'value': {'url': '%s/fake_location_2' % BASE_URI, 'metadata': {}}}, ] self.assertRaises(webob.exc.HTTPRequestEntityTooLarge, self.controller.update, request, UUID1, changes) def test_update_add_and_remove_too_many_locations(self): request = unit_test_utils.get_fake_request() changes = [ {'op': 'add', 'path': ['locations', '-'], 'value': {'url': '%s/fake_location_1' % BASE_URI, 'metadata': {}}}, {'op': 'add', 'path': ['locations', '-'], 'value': {'url': '%s/fake_location_2' % BASE_URI, 'metadata': {}}}, ] self.controller.update(request, UUID1, changes) self.config(image_location_quota=1) # We must remove two properties to avoid being # over the limit of 1 property changes = [ {'op': 'remove', 'path': ['locations', '0']}, {'op': 'add', 'path': ['locations', '-'], 'value': {'url': '%s/fake_location_3' % BASE_URI, 'metadata': {}}}, ] self.assertRaises(webob.exc.HTTPRequestEntityTooLarge, self.controller.update, request, UUID1, changes) def test_update_add_unlimited_locations(self): self.config(image_location_quota=-1) request = unit_test_utils.get_fake_request() changes = [ {'op': 'add', 'path': ['locations', '-'], 'value': {'url': '%s/fake_location_1' % BASE_URI, 'metadata': {}}}, ] output = self.controller.update(request, UUID1, changes) self.assertEqual(output.image_id, UUID1) self.assertNotEqual(output.created_at, output.updated_at) def test_update_remove_location_while_over_limit(self): """ Ensure that image locations can be removed. Image locations should be able to be removed as long as the image has fewer than the limited number of image locations after the transaction. """ request = unit_test_utils.get_fake_request() changes = [ {'op': 'add', 'path': ['locations', '-'], 'value': {'url': '%s/fake_location_1' % BASE_URI, 'metadata': {}}}, {'op': 'add', 'path': ['locations', '-'], 'value': {'url': '%s/fake_location_2' % BASE_URI, 'metadata': {}}}, ] self.controller.update(request, UUID1, changes) self.config(image_location_quota=1) self.config(show_multiple_locations=True) # We must remove two locations to avoid being over # the limit of 1 location changes = [ {'op': 'remove', 'path': ['locations', '0']}, {'op': 'remove', 'path': ['locations', '0']}, ] output = self.controller.update(request, UUID1, changes) self.assertEqual(output.image_id, UUID1) self.assertEqual(len(output.locations), 1) self.assertTrue('fake_location_2' in output.locations[0]['url']) self.assertNotEqual(output.created_at, output.updated_at) def test_update_add_and_remove_location_under_limit(self): """ Ensure that image locations can be removed. Image locations should be able to be added and removed simultaneously as long as the image has fewer than the limited number of image locations after the transaction. """ self.stubs.Set(glance.store, 'get_size_from_backend', unit_test_utils.fake_get_size_from_backend) self.config(show_multiple_locations=True) request = unit_test_utils.get_fake_request() changes = [ {'op': 'add', 'path': ['locations', '-'], 'value': {'url': '%s/fake_location_1' % BASE_URI, 'metadata': {}}}, ] self.controller.update(request, UUID1, changes) self.config(image_location_quota=1) # We must remove two properties to avoid being # over the limit of 1 property changes = [ {'op': 'remove', 'path': ['locations', '0']}, {'op': 'remove', 'path': ['locations', '0']}, {'op': 'add', 'path': ['locations', '-'], 'value': {'url': '%s/fake_location_3' % BASE_URI, 'metadata': {}}}, ] output = self.controller.update(request, UUID1, changes) self.assertEqual(output.image_id, UUID1) self.assertEqual(len(output.locations), 1) self.assertTrue('fake_location_3' in output.locations[0]['url']) self.assertNotEqual(output.created_at, output.updated_at) def test_update_remove_base_property(self): self.db.image_update(None, UUID1, {'properties': {'foo': 'bar'}}) request = unit_test_utils.get_fake_request() changes = [{'op': 'remove', 'path': ['name']}] self.assertRaises(webob.exc.HTTPForbidden, self.controller.update, request, UUID1, changes) def test_update_remove_property(self): request = unit_test_utils.get_fake_request() properties = {'foo': 'bar', 'snitch': 'golden'} self.db.image_update(None, UUID1, {'properties': properties}) output = self.controller.show(request, UUID1) self.assertEqual(output.extra_properties['foo'], 'bar') self.assertEqual(output.extra_properties['snitch'], 'golden') changes = [ {'op': 'remove', 'path': ['snitch']}, ] output = self.controller.update(request, UUID1, changes) self.assertEqual(output.image_id, UUID1) self.assertEqual(output.extra_properties, {'foo': 'bar'}) self.assertNotEqual(output.created_at, output.updated_at) def test_update_remove_missing_property(self): request = unit_test_utils.get_fake_request() changes = [ {'op': 'remove', 'path': ['foo']}, ] self.assertRaises(webob.exc.HTTPConflict, self.controller.update, request, UUID1, changes) def test_update_remove_location(self): self.stubs.Set(glance.store, 'get_size_from_backend', unit_test_utils.fake_get_size_from_backend) request = unit_test_utils.get_fake_request() changes = [{'op': 'remove', 'path': ['locations', '0']}] output = self.controller.update(request, UUID1, changes) self.assertEqual(output.image_id, UUID1) self.assertEqual(len(output.locations), 0) self.assertTrue(output.status == 'queued') self.assertIsNone(output.size) new_location = {'url': '%s/fake_location' % BASE_URI, 'metadata': {}} changes = [{'op': 'add', 'path': ['locations', '-'], 'value': new_location}] output = self.controller.update(request, UUID1, changes) self.assertEqual(output.image_id, UUID1) self.assertEqual(len(output.locations), 1) self.assertEqual(new_location, output.locations[0]) self.assertEqual(output.status, 'active') def test_update_remove_location_invalid_pos(self): request = unit_test_utils.get_fake_request() changes = [{'op': 'remove', 'path': ['locations', None]}] self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update, request, UUID1, changes) changes = [{'op': 'remove', 'path': ['locations', '-1']}] self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update, request, UUID1, changes) changes = [{'op': 'remove', 'path': ['locations', '99']}] self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update, request, UUID1, changes) changes = [{'op': 'remove', 'path': ['locations', 'x']}] self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update, request, UUID1, changes) def test_update_remove_location_store_exception(self): def fake_delete_image_from_backend(self, *args, **kwargs): raise Exception('fake_backend_exception') self.stubs.Set(glance.store, 'delete_image_from_backend', fake_delete_image_from_backend) request = unit_test_utils.get_fake_request() changes = [{'op': 'remove', 'path': ['locations', '0']}] self.assertRaises(webob.exc.HTTPInternalServerError, self.controller.update, request, UUID1, changes) def test_update_multiple_changes(self): request = unit_test_utils.get_fake_request() properties = {'foo': 'bar', 'snitch': 'golden'} self.db.image_update(None, UUID1, {'properties': properties}) changes = [ {'op': 'replace', 'path': ['min_ram'], 'value': 128}, {'op': 'replace', 'path': ['foo'], 'value': 'baz'}, {'op': 'remove', 'path': ['snitch']}, {'op': 'add', 'path': ['kb'], 'value': 'dvorak'}, ] output = self.controller.update(request, UUID1, changes) self.assertEqual(output.image_id, UUID1) self.assertEqual(output.min_ram, 128) self.addDetail('extra_properties', testtools.content.json_content( jsonutils.dumps(output.extra_properties))) self.assertEqual(len(output.extra_properties), 2) self.assertEqual(output.extra_properties['foo'], 'baz') self.assertEqual(output.extra_properties['kb'], 'dvorak') self.assertNotEqual(output.created_at, output.updated_at) def test_update_invalid_operation(self): request = unit_test_utils.get_fake_request() change = {'op': 'test', 'path': 'options', 'value': 'puts'} try: self.controller.update(request, UUID1, [change]) except AssertionError: pass # AssertionError is the desired behavior else: self.fail('Failed to raise AssertionError on %s' % change) def test_update_duplicate_tags(self): request = unit_test_utils.get_fake_request() changes = [ {'op': 'replace', 'path': ['tags'], 'value': ['ping', 'ping']}, ] output = self.controller.update(request, UUID1, changes) self.assertEqual(len(output.tags), 1) self.assertTrue('ping' in output.tags) output_logs = self.notifier.get_logs() self.assertEqual(len(output_logs), 1) output_log = output_logs[0] self.assertEqual(output_log['notification_type'], 'INFO') self.assertEqual(output_log['event_type'], 'image.update') self.assertEqual(output_log['payload']['id'], UUID1) def test_delete(self): request = unit_test_utils.get_fake_request() self.assertTrue(filter(lambda k: UUID1 in k, self.store.data)) try: self.controller.delete(request, UUID1) output_logs = self.notifier.get_logs() self.assertEqual(len(output_logs), 1) output_log = output_logs[0] self.assertEqual(output_log['notification_type'], "INFO") self.assertEqual(output_log['event_type'], "image.delete") except Exception as e: self.fail("Delete raised exception: %s" % e) deleted_img = self.db.image_get(request.context, UUID1, force_show_deleted=True) self.assertTrue(deleted_img['deleted']) self.assertEqual(deleted_img['status'], 'deleted') self.assertFalse(filter(lambda k: UUID1 in k, self.store.data)) def test_delete_queued_updates_status(self): """Ensure status of queued image is updated (LP bug #1048851)""" request = unit_test_utils.get_fake_request(is_admin=True) image = self.db.image_create(request.context, {'status': 'queued'}) image_id = image['id'] self.controller.delete(request, image_id) image = self.db.image_get(request.context, image_id, force_show_deleted=True) self.assertTrue(image['deleted']) self.assertEqual(image['status'], 'deleted') def test_delete_queued_updates_status_delayed_delete(self): """ Ensure status of queued image is updated (LP bug #1048851) to 'deleted' when delayed_delete isenabled """ self.config(delayed_delete=True) request = unit_test_utils.get_fake_request(is_admin=True) image = self.db.image_create(request.context, {'status': 'queued'}) image_id = image['id'] self.controller.delete(request, image_id) image = self.db.image_get(request.context, image_id, force_show_deleted=True) self.assertTrue(image['deleted']) self.assertEqual(image['status'], 'deleted') def test_delete_not_in_store(self): request = unit_test_utils.get_fake_request() self.assertTrue(filter(lambda k: UUID1 in k, self.store.data)) for k in self.store.data: if UUID1 in k: del self.store.data[k] break self.controller.delete(request, UUID1) deleted_img = self.db.image_get(request.context, UUID1, force_show_deleted=True) self.assertTrue(deleted_img['deleted']) self.assertEqual(deleted_img['status'], 'deleted') self.assertFalse(filter(lambda k: UUID1 in k, self.store.data)) def test_delayed_delete(self): self.config(delayed_delete=True) request = unit_test_utils.get_fake_request() self.assertTrue(filter(lambda k: UUID1 in k, self.store.data)) self.controller.delete(request, UUID1) deleted_img = self.db.image_get(request.context, UUID1, force_show_deleted=True) self.assertTrue(deleted_img['deleted']) self.assertEqual(deleted_img['status'], 'pending_delete') self.assertTrue(filter(lambda k: UUID1 in k, self.store.data)) def test_delete_non_existent(self): request = unit_test_utils.get_fake_request() self.assertRaises(webob.exc.HTTPNotFound, self.controller.delete, request, str(uuid.uuid4())) def test_delete_already_deleted_image_admin(self): request = unit_test_utils.get_fake_request(is_admin=True) self.controller.delete(request, UUID1) self.assertRaises(webob.exc.HTTPNotFound, self.controller.delete, request, UUID1) def test_delete_not_allowed(self): request = unit_test_utils.get_fake_request() self.assertRaises(webob.exc.HTTPNotFound, self.controller.delete, request, UUID4) def test_index_with_invalid_marker(self): fake_uuid = str(uuid.uuid4()) request = unit_test_utils.get_fake_request() self.assertRaises(webob.exc.HTTPBadRequest, self.controller.index, request, marker=fake_uuid) def test_invalid_locations_op_pos(self): pos = self.controller._get_locations_op_pos(None, 2, True) self.assertIsNone(pos) pos = self.controller._get_locations_op_pos('1', None, True) self.assertIsNone(pos) class TestImagesControllerPolicies(base.IsolatedUnitTest): def setUp(self): super(TestImagesControllerPolicies, self).setUp() self.db = unit_test_utils.FakeDB() self.policy = unit_test_utils.FakePolicyEnforcer() self.controller = glance.api.v2.images.ImagesController(self.db, self.policy) def test_index_unauthorized(self): rules = {"get_images": False} self.policy.set_rules(rules) request = unit_test_utils.get_fake_request() self.assertRaises(webob.exc.HTTPForbidden, self.controller.index, request) def test_show_unauthorized(self): rules = {"get_image": False} self.policy.set_rules(rules) request = unit_test_utils.get_fake_request() self.assertRaises(webob.exc.HTTPForbidden, self.controller.show, request, image_id=UUID2) def test_create_image_unauthorized(self): rules = {"add_image": False} self.policy.set_rules(rules) request = unit_test_utils.get_fake_request() image = {'name': 'image-1'} extra_properties = {} tags = [] self.assertRaises(webob.exc.HTTPForbidden, self.controller.create, request, image, extra_properties, tags) def test_create_public_image_unauthorized(self): rules = {"publicize_image": False} self.policy.set_rules(rules) request = unit_test_utils.get_fake_request() image = {'name': 'image-1', 'visibility': 'public'} extra_properties = {} tags = [] self.assertRaises(webob.exc.HTTPForbidden, self.controller.create, request, image, extra_properties, tags) def test_update_unauthorized(self): rules = {"modify_image": False} self.policy.set_rules(rules) request = unit_test_utils.get_fake_request() changes = [{'op': 'replace', 'path': ['name'], 'value': 'image-2'}] self.assertRaises(webob.exc.HTTPForbidden, self.controller.update, request, UUID1, changes) def test_update_publicize_image_unauthorized(self): rules = {"publicize_image": False} self.policy.set_rules(rules) request = unit_test_utils.get_fake_request() changes = [{'op': 'replace', 'path': ['visibility'], 'value': 'public'}] self.assertRaises(webob.exc.HTTPForbidden, self.controller.update, request, UUID1, changes) def test_update_depublicize_image_unauthorized(self): rules = {"publicize_image": False} self.policy.set_rules(rules) request = unit_test_utils.get_fake_request() changes = [{'op': 'replace', 'path': ['visibility'], 'value': 'private'}] output = self.controller.update(request, UUID1, changes) self.assertEqual(output.visibility, 'private') def test_update_get_image_location_unauthorized(self): rules = {"get_image_location": False} self.policy.set_rules(rules) request = unit_test_utils.get_fake_request() changes = [{'op': 'replace', 'path': ['locations'], 'value': []}] self.assertRaises(webob.exc.HTTPForbidden, self.controller.update, request, UUID1, changes) def test_update_set_image_location_unauthorized(self): def fake_delete_image_from_backend(self, *args, **kwargs): pass rules = {"set_image_location": False} self.policy.set_rules(rules) new_location = {'url': '%s/fake_location' % BASE_URI, 'metadata': {}} request = unit_test_utils.get_fake_request() changes = [{'op': 'add', 'path': ['locations', '-'], 'value': new_location}] self.assertRaises(webob.exc.HTTPForbidden, self.controller.update, request, UUID1, changes) self.stubs.Set(glance.store, 'delete_image_from_backend', fake_delete_image_from_backend) changes = [{'op': 'replace', 'path': ['locations'], 'value': []}] self.controller.update(request, UUID1, changes) changes = [{'op': 'replace', 'path': ['locations'], 'value': [new_location]}] self.assertRaises(webob.exc.HTTPForbidden, self.controller.update, request, UUID1, changes) def test_update_delete_image_location_unauthorized(self): rules = {"delete_image_location": False} self.policy.set_rules(rules) request = unit_test_utils.get_fake_request() changes = [{'op': 'replace', 'path': ['locations'], 'value': []}] self.assertRaises(webob.exc.HTTPForbidden, self.controller.update, request, UUID1, changes) def test_delete_unauthorized(self): rules = {"delete_image": False} self.policy.set_rules(rules) request = unit_test_utils.get_fake_request() self.assertRaises(webob.exc.HTTPForbidden, self.controller.delete, request, UUID1) class TestImagesDeserializer(test_utils.BaseTestCase): def setUp(self): super(TestImagesDeserializer, self).setUp() self.deserializer = glance.api.v2.images.RequestDeserializer() def test_create_minimal(self): request = unit_test_utils.get_fake_request() request.body = jsonutils.dumps({}) output = self.deserializer.create(request) expected = {'image': {}, 'extra_properties': {}, 'tags': None} self.assertEqual(expected, output) def test_create_invalid_id(self): request = unit_test_utils.get_fake_request() request.body = jsonutils.dumps({'id': 'gabe'}) self.assertRaises(webob.exc.HTTPBadRequest, self.deserializer.create, request) def test_create_no_body(self): request = unit_test_utils.get_fake_request() self.assertRaises(webob.exc.HTTPBadRequest, self.deserializer.create, request) def test_create_full(self): request = unit_test_utils.get_fake_request() request.body = jsonutils.dumps({ 'id': UUID3, 'name': 'image-1', 'visibility': 'public', 'tags': ['one', 'two'], 'container_format': 'ami', 'disk_format': 'ami', 'min_ram': 128, 'min_disk': 10, 'foo': 'bar', 'protected': True, }) output = self.deserializer.create(request) properties = { 'id': UUID3, 'name': 'image-1', 'visibility': 'public', 'container_format': 'ami', 'disk_format': 'ami', 'min_ram': 128, 'min_disk': 10, 'protected': True, } self.maxDiff = None expected = {'image': properties, 'extra_properties': {'foo': 'bar'}, 'tags': ['one', 'two']} self.assertEqual(expected, output) def test_create_readonly_attributes_forbidden(self): bodies = [ #{'created_at': ISOTIME}, #{'updated_at': ISOTIME}, #{'status': 'saving'}, {'direct_url': 'http://example.com'}, #{'size': 10}, #{'virtual_size': 10}, #{'checksum': 'asdf'}, {'self': 'http://example.com'}, {'file': 'http://example.com'}, {'schema': 'http://example.com'}, ] for body in bodies: request = unit_test_utils.get_fake_request() request.body = jsonutils.dumps(body) self.assertRaises(webob.exc.HTTPForbidden, self.deserializer.create, request) def _get_fake_patch_request(self, content_type_minor_version=1): request = unit_test_utils.get_fake_request() template = 'application/openstack-images-v2.%d-json-patch' request.content_type = template % content_type_minor_version return request def test_update_empty_body(self): request = self._get_fake_patch_request() request.body = jsonutils.dumps([]) output = self.deserializer.update(request) expected = {'changes': []} self.assertEqual(output, expected) def test_update_unsupported_content_type(self): request = unit_test_utils.get_fake_request() request.content_type = 'application/json-patch' request.body = jsonutils.dumps([]) try: self.deserializer.update(request) except webob.exc.HTTPUnsupportedMediaType as e: # desired result, but must have correct Accept-Patch header expected = ('application/openstack-images-v2.0-json-patch, ' 'application/openstack-images-v2.1-json-patch') self.assertEqual(e.headers['Accept-Patch'], expected) else: self.fail('Did not raise HTTPUnsupportedMediaType') def test_update_body_not_a_list(self): bodies = [ {'op': 'add', 'path': '/someprop', 'value': 'somevalue'}, 'just some string', 123, True, False, None, ] for body in bodies: request = self._get_fake_patch_request() request.body = jsonutils.dumps(body) self.assertRaises(webob.exc.HTTPBadRequest, self.deserializer.update, request) def test_update_invalid_changes(self): changes = [ ['a', 'list', 'of', 'stuff'], 'just some string', 123, True, False, None, ] for change in changes: request = self._get_fake_patch_request() request.body = jsonutils.dumps([change]) self.assertRaises(webob.exc.HTTPBadRequest, self.deserializer.update, request) def test_update(self): request = self._get_fake_patch_request() body = [ {'op': 'replace', 'path': '/name', 'value': 'fedora'}, {'op': 'replace', 'path': '/tags', 'value': ['king', 'kong']}, {'op': 'replace', 'path': '/foo', 'value': 'bar'}, {'op': 'add', 'path': '/bebim', 'value': 'bap'}, {'op': 'remove', 'path': '/sparks'}, {'op': 'add', 'path': '/locations/-', 'value': {'url': 'scheme3://path3', 'metadata': {}}}, {'op': 'add', 'path': '/locations/10', 'value': {'url': 'scheme4://path4', 'metadata': {}}}, {'op': 'remove', 'path': '/locations/2'}, {'op': 'replace', 'path': '/locations', 'value': []}, {'op': 'replace', 'path': '/locations', 'value': [{'url': 'scheme5://path5', 'metadata': {}}, {'url': 'scheme6://path6', 'metadata': {}}]}, ] request.body = jsonutils.dumps(body) output = self.deserializer.update(request) expected = {'changes': [ {'op': 'replace', 'path': ['name'], 'value': 'fedora'}, {'op': 'replace', 'path': ['tags'], 'value': ['king', 'kong']}, {'op': 'replace', 'path': ['foo'], 'value': 'bar'}, {'op': 'add', 'path': ['bebim'], 'value': 'bap'}, {'op': 'remove', 'path': ['sparks']}, {'op': 'add', 'path': ['locations', '-'], 'value': {'url': 'scheme3://path3', 'metadata': {}}}, {'op': 'add', 'path': ['locations', '10'], 'value': {'url': 'scheme4://path4', 'metadata': {}}}, {'op': 'remove', 'path': ['locations', '2']}, {'op': 'replace', 'path': ['locations'], 'value': []}, {'op': 'replace', 'path': ['locations'], 'value': [{'url': 'scheme5://path5', 'metadata': {}}, {'url': 'scheme6://path6', 'metadata': {}}]}, ]} self.assertEqual(output, expected) def test_update_v2_0_compatibility(self): request = self._get_fake_patch_request(content_type_minor_version=0) body = [ {'replace': '/name', 'value': 'fedora'}, {'replace': '/tags', 'value': ['king', 'kong']}, {'replace': '/foo', 'value': 'bar'}, {'add': '/bebim', 'value': 'bap'}, {'remove': '/sparks'}, {'add': '/locations/-', 'value': {'url': 'scheme3://path3', 'metadata': {}}}, {'add': '/locations/10', 'value': {'url': 'scheme4://path4', 'metadata': {}}}, {'remove': '/locations/2'}, {'replace': '/locations', 'value': []}, {'replace': '/locations', 'value': [{'url': 'scheme5://path5', 'metadata': {}}, {'url': 'scheme6://path6', 'metadata': {}}]}, ] request.body = jsonutils.dumps(body) output = self.deserializer.update(request) expected = {'changes': [ {'op': 'replace', 'path': ['name'], 'value': 'fedora'}, {'op': 'replace', 'path': ['tags'], 'value': ['king', 'kong']}, {'op': 'replace', 'path': ['foo'], 'value': 'bar'}, {'op': 'add', 'path': ['bebim'], 'value': 'bap'}, {'op': 'remove', 'path': ['sparks']}, {'op': 'add', 'path': ['locations', '-'], 'value': {'url': 'scheme3://path3', 'metadata': {}}}, {'op': 'add', 'path': ['locations', '10'], 'value': {'url': 'scheme4://path4', 'metadata': {}}}, {'op': 'remove', 'path': ['locations', '2']}, {'op': 'replace', 'path': ['locations'], 'value': []}, {'op': 'replace', 'path': ['locations'], 'value': [{'url': 'scheme5://path5', 'metadata': {}}, {'url': 'scheme6://path6', 'metadata': {}}]}, ]} self.assertEqual(output, expected) def test_update_base_attributes(self): request = self._get_fake_patch_request() body = [ {'op': 'replace', 'path': '/id', 'value': UUID1}, {'op': 'replace', 'path': '/name', 'value': 'fedora'}, {'op': 'replace', 'path': '/visibility', 'value': 'public'}, {'op': 'replace', 'path': '/tags', 'value': ['king', 'kong']}, {'op': 'replace', 'path': '/protected', 'value': True}, {'op': 'replace', 'path': '/container_format', 'value': 'bare'}, {'op': 'replace', 'path': '/disk_format', 'value': 'raw'}, {'op': 'replace', 'path': '/min_ram', 'value': 128}, {'op': 'replace', 'path': '/min_disk', 'value': 10}, {'op': 'replace', 'path': '/locations', 'value': []}, {'op': 'replace', 'path': '/locations', 'value': [{'url': 'scheme5://path5', 'metadata': {}}, {'url': 'scheme6://path6', 'metadata': {}}]} ] request.body = jsonutils.dumps(body) output = self.deserializer.update(request) expected = {'changes': [ {'op': 'replace', 'path': ['id'], 'value': UUID1}, {'op': 'replace', 'path': ['name'], 'value': 'fedora'}, {'op': 'replace', 'path': ['visibility'], 'value': 'public'}, {'op': 'replace', 'path': ['tags'], 'value': ['king', 'kong']}, {'op': 'replace', 'path': ['protected'], 'value': True}, {'op': 'replace', 'path': ['container_format'], 'value': 'bare'}, {'op': 'replace', 'path': ['disk_format'], 'value': 'raw'}, {'op': 'replace', 'path': ['min_ram'], 'value': 128}, {'op': 'replace', 'path': ['min_disk'], 'value': 10}, {'op': 'replace', 'path': ['locations'], 'value': []}, {'op': 'replace', 'path': ['locations'], 'value': [{'url': 'scheme5://path5', 'metadata': {}}, {'url': 'scheme6://path6', 'metadata': {}}]} ]} self.assertEqual(output, expected) def test_update_disallowed_attributes(self): samples = { 'direct_url': '/a/b/c/d', 'self': '/e/f/g/h', 'file': '/e/f/g/h/file', 'schema': '/i/j/k', } for key, value in samples.items(): request = self._get_fake_patch_request() body = [{'op': 'replace', 'path': '/%s' % key, 'value': value}] request.body = jsonutils.dumps(body) try: self.deserializer.update(request) except webob.exc.HTTPForbidden: pass # desired behavior else: self.fail("Updating %s did not result in HTTPForbidden" % key) def test_update_readonly_attributes(self): samples = { 'status': 'active', 'checksum': 'abcdefghijklmnopqrstuvwxyz012345', 'size': 9001, 'virtual_size': 9001, 'created_at': ISOTIME, 'updated_at': ISOTIME, } for key, value in samples.items(): request = self._get_fake_patch_request() body = [{'op': 'replace', 'path': '/%s' % key, 'value': value}] request.body = jsonutils.dumps(body) try: self.deserializer.update(request) except webob.exc.HTTPForbidden: pass # desired behavior else: self.fail("Updating %s did not result in HTTPForbidden" % key) def test_update_reserved_attributes(self): samples = { 'owner': TENANT1, 'is_public': True, 'deleted': False, 'deleted_at': ISOTIME, } for key, value in samples.items(): request = self._get_fake_patch_request() body = [{'op': 'replace', 'path': '/%s' % key, 'value': value}] request.body = jsonutils.dumps(body) try: self.deserializer.update(request) except webob.exc.HTTPForbidden: pass # desired behavior else: self.fail("Updating %s did not result in HTTPForbidden" % key) def test_update_invalid_attributes(self): keys = [ 'noslash', '///twoslash', '/two/ /slash', '/ / ', '/trailingslash/', '/lone~tilde', '/trailingtilde~' ] for key in keys: request = self._get_fake_patch_request() body = [{'op': 'replace', 'path': '%s' % key, 'value': 'dummy'}] request.body = jsonutils.dumps(body) try: self.deserializer.update(request) except webob.exc.HTTPBadRequest: pass # desired behavior else: self.fail("Updating %s did not result in HTTPBadRequest" % key) def test_update_pointer_encoding(self): samples = { '/keywith~1slash': [u'keywith/slash'], '/keywith~0tilde': [u'keywith~tilde'], '/tricky~01': [u'tricky~1'], } for encoded, decoded in samples.items(): request = self._get_fake_patch_request() doc = [{'op': 'replace', 'path': '%s' % encoded, 'value': 'dummy'}] request.body = jsonutils.dumps(doc) output = self.deserializer.update(request) self.assertEqual(output['changes'][0]['path'], decoded) def test_update_deep_limited_attributes(self): samples = { 'locations/1/2': [], } for key, value in samples.items(): request = self._get_fake_patch_request() body = [{'op': 'replace', 'path': '/%s' % key, 'value': value}] request.body = jsonutils.dumps(body) try: self.deserializer.update(request) except webob.exc.HTTPBadRequest: pass # desired behavior else: self.fail("Updating %s did not result in HTTPBadRequest" % key) def test_update_v2_1_missing_operations(self): request = self._get_fake_patch_request() body = [{'path': '/colburn', 'value': 'arcata'}] request.body = jsonutils.dumps(body) self.assertRaises(webob.exc.HTTPBadRequest, self.deserializer.update, request) def test_update_v2_1_missing_value(self): request = self._get_fake_patch_request() body = [{'op': 'replace', 'path': '/colburn'}] request.body = jsonutils.dumps(body) self.assertRaises(webob.exc.HTTPBadRequest, self.deserializer.update, request) def test_update_v2_1_missing_path(self): request = self._get_fake_patch_request() body = [{'op': 'replace', 'value': 'arcata'}] request.body = jsonutils.dumps(body) self.assertRaises(webob.exc.HTTPBadRequest, self.deserializer.update, request) def test_update_v2_0_multiple_operations(self): request = self._get_fake_patch_request(content_type_minor_version=0) body = [{'replace': '/foo', 'add': '/bar', 'value': 'snore'}] request.body = jsonutils.dumps(body) self.assertRaises(webob.exc.HTTPBadRequest, self.deserializer.update, request) def test_update_v2_0_missing_operations(self): request = self._get_fake_patch_request(content_type_minor_version=0) body = [{'value': 'arcata'}] request.body = jsonutils.dumps(body) self.assertRaises(webob.exc.HTTPBadRequest, self.deserializer.update, request) def test_update_v2_0_missing_value(self): request = self._get_fake_patch_request(content_type_minor_version=0) body = [{'replace': '/colburn'}] request.body = jsonutils.dumps(body) self.assertRaises(webob.exc.HTTPBadRequest, self.deserializer.update, request) def test_index(self): marker = str(uuid.uuid4()) path = '/images?limit=1&marker=%s&member_status=pending' % marker request = unit_test_utils.get_fake_request(path) expected = {'limit': 1, 'marker': marker, 'sort_key': 'created_at', 'sort_dir': 'desc', 'member_status': 'pending', 'filters': {}} output = self.deserializer.index(request) self.assertEqual(output, expected) def test_index_with_filter(self): name = 'My Little Image' path = '/images?name=%s' % name request = unit_test_utils.get_fake_request(path) output = self.deserializer.index(request) self.assertEqual(output['filters']['name'], name) def test_index_strip_params_from_filters(self): name = 'My Little Image' path = '/images?name=%s' % name request = unit_test_utils.get_fake_request(path) output = self.deserializer.index(request) self.assertEqual(output['filters']['name'], name) self.assertEqual(len(output['filters']), 1) def test_index_with_many_filter(self): name = 'My Little Image' instance_id = str(uuid.uuid4()) path = ('/images?name=%(name)s&id=%(instance_id)s' % {'name': name, 'instance_id': instance_id}) request = unit_test_utils.get_fake_request(path) output = self.deserializer.index(request) self.assertEqual(output['filters']['name'], name) self.assertEqual(output['filters']['id'], instance_id) def test_index_with_filter_and_limit(self): name = 'My Little Image' path = '/images?name=%s&limit=1' % name request = unit_test_utils.get_fake_request(path) output = self.deserializer.index(request) self.assertEqual(output['filters']['name'], name) self.assertEqual(output['limit'], 1) def test_index_non_integer_limit(self): request = unit_test_utils.get_fake_request('/images?limit=blah') self.assertRaises(webob.exc.HTTPBadRequest, self.deserializer.index, request) def test_index_zero_limit(self): request = unit_test_utils.get_fake_request('/images?limit=0') expected = {'limit': 0, 'sort_key': 'created_at', 'member_status': 'accepted', 'sort_dir': 'desc', 'filters': {}} output = self.deserializer.index(request) self.assertEqual(expected, output) def test_index_negative_limit(self): request = unit_test_utils.get_fake_request('/images?limit=-1') self.assertRaises(webob.exc.HTTPBadRequest, self.deserializer.index, request) def test_index_fraction(self): request = unit_test_utils.get_fake_request('/images?limit=1.1') self.assertRaises(webob.exc.HTTPBadRequest, self.deserializer.index, request) def test_index_invalid_status(self): path = '/images?member_status=blah' request = unit_test_utils.get_fake_request(path) self.assertRaises(webob.exc.HTTPBadRequest, self.deserializer.index, request) def test_index_marker(self): marker = str(uuid.uuid4()) path = '/images?marker=%s' % marker request = unit_test_utils.get_fake_request(path) output = self.deserializer.index(request) self.assertEqual(output.get('marker'), marker) def test_index_marker_not_specified(self): request = unit_test_utils.get_fake_request('/images') output = self.deserializer.index(request) self.assertFalse('marker' in output) def test_index_limit_not_specified(self): request = unit_test_utils.get_fake_request('/images') output = self.deserializer.index(request) self.assertFalse('limit' in output) def test_index_sort_key_id(self): request = unit_test_utils.get_fake_request('/images?sort_key=id') output = self.deserializer.index(request) expected = { 'sort_key': 'id', 'sort_dir': 'desc', 'member_status': 'accepted', 'filters': {} } self.assertEqual(output, expected) def test_index_sort_dir_asc(self): request = unit_test_utils.get_fake_request('/images?sort_dir=asc') output = self.deserializer.index(request) expected = { 'sort_key': 'created_at', 'sort_dir': 'asc', 'member_status': 'accepted', 'filters': {}} self.assertEqual(output, expected) def test_index_sort_dir_bad_value(self): request = unit_test_utils.get_fake_request('/images?sort_dir=blah') self.assertRaises(webob.exc.HTTPBadRequest, self.deserializer.index, request) def test_index_with_tag(self): path = '/images?tag=%s&tag=%s' % ('x86', '64bit') request = unit_test_utils.get_fake_request(path) output = self.deserializer.index(request) self.assertEqual(sorted(output['filters']['tags']), sorted(['x86', '64bit'])) class TestImagesDeserializerWithExtendedSchema(test_utils.BaseTestCase): def setUp(self): super(TestImagesDeserializerWithExtendedSchema, self).setUp() self.config(allow_additional_image_properties=False) custom_image_properties = { 'pants': { 'type': 'string', 'enum': ['on', 'off'], }, } schema = glance.api.v2.images.get_schema(custom_image_properties) self.deserializer = glance.api.v2.images.RequestDeserializer(schema) def test_create(self): request = unit_test_utils.get_fake_request() request.body = jsonutils.dumps({'name': 'image-1', 'pants': 'on'}) output = self.deserializer.create(request) expected = { 'image': {'name': 'image-1'}, 'extra_properties': {'pants': 'on'}, 'tags': None, } self.assertEqual(expected, output) def test_create_bad_data(self): request = unit_test_utils.get_fake_request() request.body = jsonutils.dumps({'name': 'image-1', 'pants': 'borked'}) self.assertRaises(webob.exc.HTTPBadRequest, self.deserializer.create, request) def test_update(self): request = unit_test_utils.get_fake_request() request.content_type = 'application/openstack-images-v2.1-json-patch' doc = [{'op': 'add', 'path': '/pants', 'value': 'off'}] request.body = jsonutils.dumps(doc) output = self.deserializer.update(request) expected = {'changes': [ {'op': 'add', 'path': ['pants'], 'value': 'off'}, ]} self.assertEqual(expected, output) def test_update_bad_data(self): request = unit_test_utils.get_fake_request() request.content_type = 'application/openstack-images-v2.1-json-patch' doc = [{'op': 'add', 'path': '/pants', 'value': 'cutoffs'}] request.body = jsonutils.dumps(doc) self.assertRaises(webob.exc.HTTPBadRequest, self.deserializer.update, request) class TestImagesDeserializerWithAdditionalProperties(test_utils.BaseTestCase): def setUp(self): super(TestImagesDeserializerWithAdditionalProperties, self).setUp() self.config(allow_additional_image_properties=True) self.deserializer = glance.api.v2.images.RequestDeserializer() def test_create(self): request = unit_test_utils.get_fake_request() request.body = jsonutils.dumps({'foo': 'bar'}) output = self.deserializer.create(request) expected = {'image': {}, 'extra_properties': {'foo': 'bar'}, 'tags': None} self.assertEqual(expected, output) def test_create_with_numeric_property(self): request = unit_test_utils.get_fake_request() request.body = jsonutils.dumps({'abc': 123}) self.assertRaises(webob.exc.HTTPBadRequest, self.deserializer.create, request) def test_update_with_numeric_property(self): request = unit_test_utils.get_fake_request() request.content_type = 'application/openstack-images-v2.1-json-patch' doc = [{'op': 'add', 'path': '/foo', 'value': 123}] request.body = jsonutils.dumps(doc) self.assertRaises(webob.exc.HTTPBadRequest, self.deserializer.update, request) def test_create_with_list_property(self): request = unit_test_utils.get_fake_request() request.body = jsonutils.dumps({'foo': ['bar']}) self.assertRaises(webob.exc.HTTPBadRequest, self.deserializer.create, request) def test_update_with_list_property(self): request = unit_test_utils.get_fake_request() request.content_type = 'application/openstack-images-v2.1-json-patch' doc = [{'op': 'add', 'path': '/foo', 'value': ['bar', 'baz']}] request.body = jsonutils.dumps(doc) self.assertRaises(webob.exc.HTTPBadRequest, self.deserializer.update, request) def test_update(self): request = unit_test_utils.get_fake_request() request.content_type = 'application/openstack-images-v2.1-json-patch' doc = [{'op': 'add', 'path': '/foo', 'value': 'bar'}] request.body = jsonutils.dumps(doc) output = self.deserializer.update(request) change = {'op': 'add', 'path': ['foo'], 'value': 'bar'} self.assertEqual(output, {'changes': [change]}) class TestImagesDeserializerNoAdditionalProperties(test_utils.BaseTestCase): def setUp(self): super(TestImagesDeserializerNoAdditionalProperties, self).setUp() self.config(allow_additional_image_properties=False) self.deserializer = glance.api.v2.images.RequestDeserializer() def test_create_with_additional_properties_disallowed(self): self.config(allow_additional_image_properties=False) request = unit_test_utils.get_fake_request() request.body = jsonutils.dumps({'foo': 'bar'}) self.assertRaises(webob.exc.HTTPBadRequest, self.deserializer.create, request) def test_update(self): request = unit_test_utils.get_fake_request() request.content_type = 'application/openstack-images-v2.1-json-patch' doc = [{'op': 'add', 'path': '/foo', 'value': 'bar'}] request.body = jsonutils.dumps(doc) self.assertRaises(webob.exc.HTTPBadRequest, self.deserializer.update, request) class TestImagesSerializer(test_utils.BaseTestCase): def setUp(self): super(TestImagesSerializer, self).setUp() self.serializer = glance.api.v2.images.ResponseSerializer() self.fixtures = [ #NOTE(bcwaldon): This first fixture has every property defined _domain_fixture(UUID1, name='image-1', size=1024, virtual_size=3072, created_at=DATETIME, updated_at=DATETIME, owner=TENANT1, visibility='public', container_format='ami', tags=['one', 'two'], disk_format='ami', min_ram=128, min_disk=10, checksum='ca425b88f047ce8ec45ee90e813ada91'), #NOTE(bcwaldon): This second fixture depends on default behavior # and sets most values to None _domain_fixture(UUID2, created_at=DATETIME, updated_at=DATETIME), ] def test_index(self): expected = { 'images': [ { 'id': UUID1, 'name': 'image-1', 'status': 'queued', 'visibility': 'public', 'protected': False, 'tags': set(['one', 'two']), 'size': 1024, 'virtual_size': 3072, 'checksum': 'ca425b88f047ce8ec45ee90e813ada91', 'container_format': 'ami', 'disk_format': 'ami', 'min_ram': 128, 'min_disk': 10, 'created_at': ISOTIME, 'updated_at': ISOTIME, 'self': '/v2/images/%s' % UUID1, 'file': '/v2/images/%s/file' % UUID1, 'schema': '/v2/schemas/image', 'owner': '6838eb7b-6ded-434a-882c-b344c77fe8df', }, { 'id': UUID2, 'status': 'queued', 'visibility': 'private', 'protected': False, 'tags': set([]), 'created_at': ISOTIME, 'updated_at': ISOTIME, 'self': '/v2/images/%s' % UUID2, 'file': '/v2/images/%s/file' % UUID2, 'schema': '/v2/schemas/image', }, ], 'first': '/v2/images', 'schema': '/v2/schemas/images', } request = webob.Request.blank('/v2/images') response = webob.Response(request=request) result = {'images': self.fixtures} self.serializer.index(response, result) actual = jsonutils.loads(response.body) for image in actual['images']: image['tags'] = set(image['tags']) self.assertEqual(expected, actual) self.assertEqual('application/json', response.content_type) def test_index_next_marker(self): request = webob.Request.blank('/v2/images') response = webob.Response(request=request) result = {'images': self.fixtures, 'next_marker': UUID2} self.serializer.index(response, result) output = jsonutils.loads(response.body) self.assertEqual('/v2/images?marker=%s' % UUID2, output['next']) def test_index_carries_query_parameters(self): url = '/v2/images?limit=10&sort_key=id&sort_dir=asc' request = webob.Request.blank(url) response = webob.Response(request=request) result = {'images': self.fixtures, 'next_marker': UUID2} self.serializer.index(response, result) output = jsonutils.loads(response.body) self.assertEqual('/v2/images?sort_key=id&sort_dir=asc&limit=10', output['first']) expect_next = '/v2/images?sort_key=id&sort_dir=asc&limit=10&marker=%s' self.assertEqual(expect_next % UUID2, output['next']) def test_index_forbidden_get_image_location(self): """Make sure the serializer works fine no mater if current user is authorized to get image location if the show_multiple_locations is False. """ class ImageLocations(object): def __len__(self): raise exception.Forbidden() self.config(show_multiple_locations=False) self.config(show_image_direct_url=False) url = '/v2/images?limit=10&sort_key=id&sort_dir=asc' request = webob.Request.blank(url) response = webob.Response(request=request) result = {'images': self.fixtures} self.assertEqual(response.status_int, 200) # The image index should work though the user is forbidden result['images'][0].locations = ImageLocations() self.serializer.index(response, result) self.assertEqual(response.status_int, 200) def test_show_full_fixture(self): expected = { 'id': UUID1, 'name': 'image-1', 'status': 'queued', 'visibility': 'public', 'protected': False, 'tags': set(['one', 'two']), 'size': 1024, 'virtual_size': 3072, 'checksum': 'ca425b88f047ce8ec45ee90e813ada91', 'container_format': 'ami', 'disk_format': 'ami', 'min_ram': 128, 'min_disk': 10, 'created_at': ISOTIME, 'updated_at': ISOTIME, 'self': '/v2/images/%s' % UUID1, 'file': '/v2/images/%s/file' % UUID1, 'schema': '/v2/schemas/image', 'owner': '6838eb7b-6ded-434a-882c-b344c77fe8df', } response = webob.Response() self.serializer.show(response, self.fixtures[0]) actual = jsonutils.loads(response.body) actual['tags'] = set(actual['tags']) self.assertEqual(expected, actual) self.assertEqual('application/json', response.content_type) def test_show_minimal_fixture(self): expected = { 'id': UUID2, 'status': 'queued', 'visibility': 'private', 'protected': False, 'tags': [], 'created_at': ISOTIME, 'updated_at': ISOTIME, 'self': '/v2/images/%s' % UUID2, 'file': '/v2/images/%s/file' % UUID2, 'schema': '/v2/schemas/image', } response = webob.Response() self.serializer.show(response, self.fixtures[1]) self.assertEqual(expected, jsonutils.loads(response.body)) def test_create(self): expected = { 'id': UUID1, 'name': 'image-1', 'status': 'queued', 'visibility': 'public', 'protected': False, 'tags': ['two', 'one'], 'size': 1024, 'virtual_size': 3072, 'checksum': 'ca425b88f047ce8ec45ee90e813ada91', 'container_format': 'ami', 'disk_format': 'ami', 'min_ram': 128, 'min_disk': 10, 'created_at': ISOTIME, 'updated_at': ISOTIME, 'self': '/v2/images/%s' % UUID1, 'file': '/v2/images/%s/file' % UUID1, 'schema': '/v2/schemas/image', 'owner': '6838eb7b-6ded-434a-882c-b344c77fe8df', } response = webob.Response() self.serializer.create(response, self.fixtures[0]) self.assertEqual(response.status_int, 201) self.assertEqual(expected, jsonutils.loads(response.body)) self.assertEqual('application/json', response.content_type) self.assertEqual(response.location, '/v2/images/%s' % UUID1) def test_update(self): expected = { 'id': UUID1, 'name': 'image-1', 'status': 'queued', 'visibility': 'public', 'protected': False, 'tags': set(['one', 'two']), 'size': 1024, 'virtual_size': 3072, 'checksum': 'ca425b88f047ce8ec45ee90e813ada91', 'container_format': 'ami', 'disk_format': 'ami', 'min_ram': 128, 'min_disk': 10, 'created_at': ISOTIME, 'updated_at': ISOTIME, 'self': '/v2/images/%s' % UUID1, 'file': '/v2/images/%s/file' % UUID1, 'schema': '/v2/schemas/image', 'owner': '6838eb7b-6ded-434a-882c-b344c77fe8df', } response = webob.Response() self.serializer.update(response, self.fixtures[0]) actual = jsonutils.loads(response.body) actual['tags'] = set(actual['tags']) self.assertEqual(expected, actual) self.assertEqual('application/json', response.content_type) class TestImagesSerializerWithUnicode(test_utils.BaseTestCase): def setUp(self): super(TestImagesSerializerWithUnicode, self).setUp() self.serializer = glance.api.v2.images.ResponseSerializer() self.fixtures = [ #NOTE(bcwaldon): This first fixture has every property defined _domain_fixture(UUID1, **{ 'name': u'OpenStack\u2122-1', 'size': 1024, 'virtual_size': 3072, 'tags': [u'\u2160', u'\u2161'], 'created_at': DATETIME, 'updated_at': DATETIME, 'owner': TENANT1, 'visibility': 'public', 'container_format': 'ami', 'disk_format': 'ami', 'min_ram': 128, 'min_disk': 10, 'checksum': u'ca425b88f047ce8ec45ee90e813ada91', 'extra_properties': {'lang': u'Fran\u00E7ais', u'dispos\u00E9': u'f\u00E2ch\u00E9'}, }), ] def test_index(self): expected = { u'images': [ { u'id': UUID1, u'name': u'OpenStack\u2122-1', u'status': u'queued', u'visibility': u'public', u'protected': False, u'tags': [u'\u2161', u'\u2160'], u'size': 1024, u'virtual_size': 3072, u'checksum': u'ca425b88f047ce8ec45ee90e813ada91', u'container_format': u'ami', u'disk_format': u'ami', u'min_ram': 128, u'min_disk': 10, u'created_at': unicode(ISOTIME), u'updated_at': unicode(ISOTIME), u'self': u'/v2/images/%s' % UUID1, u'file': u'/v2/images/%s/file' % UUID1, u'schema': u'/v2/schemas/image', u'lang': u'Fran\u00E7ais', u'dispos\u00E9': u'f\u00E2ch\u00E9', u'owner': u'6838eb7b-6ded-434a-882c-b344c77fe8df', }, ], u'first': u'/v2/images', u'schema': u'/v2/schemas/images', } request = webob.Request.blank('/v2/images') response = webob.Response(request=request) result = {u'images': self.fixtures} self.serializer.index(response, result) self.assertEqual(expected, jsonutils.loads(response.body)) self.assertEqual('application/json', response.content_type) def test_show_full_fixture(self): expected = { u'id': UUID1, u'name': u'OpenStack\u2122-1', u'status': u'queued', u'visibility': u'public', u'protected': False, u'tags': set([u'\u2160', u'\u2161']), u'size': 1024, u'virtual_size': 3072, u'checksum': u'ca425b88f047ce8ec45ee90e813ada91', u'container_format': u'ami', u'disk_format': u'ami', u'min_ram': 128, u'min_disk': 10, u'created_at': unicode(ISOTIME), u'updated_at': unicode(ISOTIME), u'self': u'/v2/images/%s' % UUID1, u'file': u'/v2/images/%s/file' % UUID1, u'schema': u'/v2/schemas/image', u'lang': u'Fran\u00E7ais', u'dispos\u00E9': u'f\u00E2ch\u00E9', u'owner': u'6838eb7b-6ded-434a-882c-b344c77fe8df', } response = webob.Response() self.serializer.show(response, self.fixtures[0]) actual = jsonutils.loads(response.body) actual['tags'] = set(actual['tags']) self.assertEqual(expected, actual) self.assertEqual('application/json', response.content_type) def test_create(self): expected = { u'id': UUID1, u'name': u'OpenStack\u2122-1', u'status': u'queued', u'visibility': u'public', u'protected': False, u'tags': [u'\u2161', u'\u2160'], u'size': 1024, u'virtual_size': 3072, u'checksum': u'ca425b88f047ce8ec45ee90e813ada91', u'container_format': u'ami', u'disk_format': u'ami', u'min_ram': 128, u'min_disk': 10, u'created_at': unicode(ISOTIME), u'updated_at': unicode(ISOTIME), u'self': u'/v2/images/%s' % UUID1, u'file': u'/v2/images/%s/file' % UUID1, u'schema': u'/v2/schemas/image', u'lang': u'Fran\u00E7ais', u'dispos\u00E9': u'f\u00E2ch\u00E9', u'owner': u'6838eb7b-6ded-434a-882c-b344c77fe8df', } response = webob.Response() self.serializer.create(response, self.fixtures[0]) self.assertEqual(response.status_int, 201) self.assertEqual(expected, jsonutils.loads(response.body)) self.assertEqual('application/json', response.content_type) self.assertEqual(response.location, '/v2/images/%s' % UUID1) def test_update(self): expected = { u'id': UUID1, u'name': u'OpenStack\u2122-1', u'status': u'queued', u'visibility': u'public', u'protected': False, u'tags': set([u'\u2160', u'\u2161']), u'size': 1024, u'virtual_size': 3072, u'checksum': u'ca425b88f047ce8ec45ee90e813ada91', u'container_format': u'ami', u'disk_format': u'ami', u'min_ram': 128, u'min_disk': 10, u'created_at': unicode(ISOTIME), u'updated_at': unicode(ISOTIME), u'self': u'/v2/images/%s' % UUID1, u'file': u'/v2/images/%s/file' % UUID1, u'schema': u'/v2/schemas/image', u'lang': u'Fran\u00E7ais', u'dispos\u00E9': u'f\u00E2ch\u00E9', u'owner': u'6838eb7b-6ded-434a-882c-b344c77fe8df', } response = webob.Response() self.serializer.update(response, self.fixtures[0]) actual = jsonutils.loads(response.body) actual['tags'] = set(actual['tags']) self.assertEqual(expected, actual) self.assertEqual('application/json', response.content_type) class TestImagesSerializerWithExtendedSchema(test_utils.BaseTestCase): def setUp(self): super(TestImagesSerializerWithExtendedSchema, self).setUp() self.config(allow_additional_image_properties=False) custom_image_properties = { 'color': { 'type': 'string', 'enum': ['red', 'green'], }, } schema = glance.api.v2.images.get_schema(custom_image_properties) self.serializer = glance.api.v2.images.ResponseSerializer(schema) props = dict(color='green', mood='grouchy') self.fixture = _domain_fixture( UUID2, name='image-2', owner=TENANT2, checksum='ca425b88f047ce8ec45ee90e813ada91', created_at=DATETIME, updated_at=DATETIME, size=1024, virtual_size=3072, extra_properties=props) def test_show(self): expected = { 'id': UUID2, 'name': 'image-2', 'status': 'queued', 'visibility': 'private', 'protected': False, 'checksum': 'ca425b88f047ce8ec45ee90e813ada91', 'tags': [], 'size': 1024, 'virtual_size': 3072, 'owner': '2c014f32-55eb-467d-8fcb-4bd706012f81', 'color': 'green', 'created_at': ISOTIME, 'updated_at': ISOTIME, 'self': '/v2/images/%s' % UUID2, 'file': '/v2/images/%s/file' % UUID2, 'schema': '/v2/schemas/image', } response = webob.Response() self.serializer.show(response, self.fixture) self.assertEqual(expected, jsonutils.loads(response.body)) def test_show_reports_invalid_data(self): self.fixture.extra_properties['color'] = 'invalid' expected = { 'id': UUID2, 'name': 'image-2', 'status': 'queued', 'visibility': 'private', 'protected': False, 'checksum': 'ca425b88f047ce8ec45ee90e813ada91', 'tags': [], 'size': 1024, 'virtual_size': 3072, 'owner': '2c014f32-55eb-467d-8fcb-4bd706012f81', 'color': 'invalid', 'created_at': ISOTIME, 'updated_at': ISOTIME, 'self': '/v2/images/%s' % UUID2, 'file': '/v2/images/%s/file' % UUID2, 'schema': '/v2/schemas/image', } response = webob.Response() self.serializer.show(response, self.fixture) self.assertEqual(expected, jsonutils.loads(response.body)) class TestImagesSerializerWithAdditionalProperties(test_utils.BaseTestCase): def setUp(self): super(TestImagesSerializerWithAdditionalProperties, self).setUp() self.config(allow_additional_image_properties=True) self.fixture = _domain_fixture( UUID2, name='image-2', owner=TENANT2, checksum='ca425b88f047ce8ec45ee90e813ada91', created_at=DATETIME, updated_at=DATETIME, size=1024, virtual_size=3072, extra_properties={'marx': 'groucho'}) def test_show(self): serializer = glance.api.v2.images.ResponseSerializer() expected = { 'id': UUID2, 'name': 'image-2', 'status': 'queued', 'visibility': 'private', 'protected': False, 'checksum': 'ca425b88f047ce8ec45ee90e813ada91', 'marx': 'groucho', 'tags': [], 'size': 1024, 'virtual_size': 3072, 'created_at': ISOTIME, 'updated_at': ISOTIME, 'self': '/v2/images/%s' % UUID2, 'file': '/v2/images/%s/file' % UUID2, 'schema': '/v2/schemas/image', 'owner': '2c014f32-55eb-467d-8fcb-4bd706012f81', } response = webob.Response() serializer.show(response, self.fixture) self.assertEqual(expected, jsonutils.loads(response.body)) def test_show_invalid_additional_property(self): """Ensure that the serializer passes through invalid additional properties (i.e. non-string) without complaining. """ serializer = glance.api.v2.images.ResponseSerializer() self.fixture.extra_properties['marx'] = 123 expected = { 'id': UUID2, 'name': 'image-2', 'status': 'queued', 'visibility': 'private', 'protected': False, 'checksum': 'ca425b88f047ce8ec45ee90e813ada91', 'marx': 123, 'tags': [], 'size': 1024, 'virtual_size': 3072, 'created_at': ISOTIME, 'updated_at': ISOTIME, 'self': '/v2/images/%s' % UUID2, 'file': '/v2/images/%s/file' % UUID2, 'schema': '/v2/schemas/image', 'owner': '2c014f32-55eb-467d-8fcb-4bd706012f81', } response = webob.Response() serializer.show(response, self.fixture) self.assertEqual(expected, jsonutils.loads(response.body)) def test_show_with_additional_properties_disabled(self): self.config(allow_additional_image_properties=False) serializer = glance.api.v2.images.ResponseSerializer() expected = { 'id': UUID2, 'name': 'image-2', 'status': 'queued', 'visibility': 'private', 'protected': False, 'checksum': 'ca425b88f047ce8ec45ee90e813ada91', 'tags': [], 'size': 1024, 'virtual_size': 3072, 'owner': '2c014f32-55eb-467d-8fcb-4bd706012f81', 'created_at': ISOTIME, 'updated_at': ISOTIME, 'self': '/v2/images/%s' % UUID2, 'file': '/v2/images/%s/file' % UUID2, 'schema': '/v2/schemas/image', } response = webob.Response() serializer.show(response, self.fixture) self.assertEqual(expected, jsonutils.loads(response.body)) class TestImagesSerializerDirectUrl(test_utils.BaseTestCase): def setUp(self): super(TestImagesSerializerDirectUrl, self).setUp() self.serializer = glance.api.v2.images.ResponseSerializer() self.active_image = _domain_fixture( UUID1, name='image-1', visibility='public', status='active', size=1024, virtual_size=3072, created_at=DATETIME, updated_at=DATETIME, locations=[{'url': 'http://some/fake/location', 'metadata': {}}]) self.queued_image = _domain_fixture( UUID2, name='image-2', status='active', created_at=DATETIME, updated_at=DATETIME, checksum='ca425b88f047ce8ec45ee90e813ada91') self.location_data_image_url = 'http://abc.com/somewhere' self.location_data_image_meta = {'key': 98231} self.location_data_image = _domain_fixture( UUID2, name='image-2', status='active', created_at=DATETIME, updated_at=DATETIME, locations=[{'url': self.location_data_image_url, 'metadata': self.location_data_image_meta}]) def _do_index(self): request = webob.Request.blank('/v2/images') response = webob.Response(request=request) self.serializer.index(response, {'images': [self.active_image, self.queued_image]}) return jsonutils.loads(response.body)['images'] def _do_show(self, image): request = webob.Request.blank('/v2/images') response = webob.Response(request=request) self.serializer.show(response, image) return jsonutils.loads(response.body) def test_index_store_location_enabled(self): self.config(show_image_direct_url=True) images = self._do_index() # NOTE(markwash): ordering sanity check self.assertEqual(images[0]['id'], UUID1) self.assertEqual(images[1]['id'], UUID2) self.assertEqual(images[0]['direct_url'], 'http://some/fake/location') self.assertFalse('direct_url' in images[1]) def test_index_store_multiple_location_enabled(self): self.config(show_multiple_locations=True) request = webob.Request.blank('/v2/images') response = webob.Response(request=request) self.serializer.index(response, {'images': [self.location_data_image]}), images = jsonutils.loads(response.body)['images'] location = images[0]['locations'][0] self.assertEqual(location['url'], self.location_data_image_url) self.assertEqual(location['metadata'], self.location_data_image_meta) def test_index_store_location_explicitly_disabled(self): self.config(show_image_direct_url=False) images = self._do_index() self.assertFalse('direct_url' in images[0]) self.assertFalse('direct_url' in images[1]) def test_show_location_enabled(self): self.config(show_image_direct_url=True) image = self._do_show(self.active_image) self.assertEqual(image['direct_url'], 'http://some/fake/location') def test_show_location_enabled_but_not_set(self): self.config(show_image_direct_url=True) image = self._do_show(self.queued_image) self.assertFalse('direct_url' in image) def test_show_location_explicitly_disabled(self): self.config(show_image_direct_url=False) image = self._do_show(self.active_image) self.assertFalse('direct_url' in image) class TestImageSchemaFormatConfiguration(test_utils.BaseTestCase): def test_default_disk_formats(self): schema = glance.api.v2.images.get_schema() expected = ['ami', 'ari', 'aki', 'vhd', 'vmdk', 'raw', 'qcow2', 'vdi', 'iso'] actual = schema.properties['disk_format']['enum'] self.assertEqual(expected, actual) def test_custom_disk_formats(self): self.config(disk_formats=['gabe'], group="image_format") schema = glance.api.v2.images.get_schema() expected = ['gabe'] actual = schema.properties['disk_format']['enum'] self.assertEqual(expected, actual) def test_default_container_formats(self): schema = glance.api.v2.images.get_schema() expected = ['ami', 'ari', 'aki', 'bare', 'ovf', 'ova'] actual = schema.properties['container_format']['enum'] self.assertEqual(expected, actual) def test_custom_container_formats(self): self.config(container_formats=['mark'], group="image_format") schema = glance.api.v2.images.get_schema() expected = ['mark'] actual = schema.properties['container_format']['enum'] self.assertEqual(expected, actual) glance-2014.1/glance/tests/unit/v2/test_registry_client.py0000664000175400017540000006007112323736226024722 0ustar jenkinsjenkins00000000000000# Copyright 2013 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. """ Tests for Glance Registry's client. This tests are temporary and will be removed once the registry's driver tests will be added. """ import copy import datetime import os import uuid import mox from glance.common import config from glance.common import exception from glance import context from glance.db.sqlalchemy import api as db_api from glance.openstack.common import timeutils from glance.registry.api import v2 as rserver import glance.registry.client.v2.api as rapi from glance.registry.client.v2.api import client as rclient from glance.tests.unit import base from glance.tests import utils as test_utils _gen_uuid = lambda: str(uuid.uuid4()) UUID1 = str(uuid.uuid4()) UUID2 = str(uuid.uuid4()) #NOTE(bcwaldon): needed to init config_dir cli opt config.parse_args(args=[]) class TestRegistryV2Client(base.IsolatedUnitTest, test_utils.RegistryAPIMixIn): """ Test proper actions made for both valid and invalid requests against a Registry service """ # Registry server to user # in the stub. registry = rserver def setUp(self): """Establish a clean test environment""" super(TestRegistryV2Client, self).setUp() db_api.get_engine() self.context = context.RequestContext(is_admin=True) uuid1_time = timeutils.utcnow() uuid2_time = uuid1_time + datetime.timedelta(seconds=5) self.FIXTURES = [ self.get_extra_fixture( id=UUID1, name='fake image #1', is_public=False, disk_format='ami', container_format='ami', size=13, virtual_size=26, properties={'type': 'kernel'}, location="swift://user:passwd@acct/container/obj.tar.0", created_at=uuid1_time), self.get_extra_fixture(id=UUID2, name='fake image #2', properties={}, size=19, virtual_size=38, location="file:///tmp/glance-tests/2", created_at=uuid2_time)] self.destroy_fixtures() self.create_fixtures() self.client = rclient.RegistryClient("0.0.0.0") def tearDown(self): """Clear the test environment""" super(TestRegistryV2Client, self).tearDown() self.destroy_fixtures() def test_image_get_index(self): """Test correct set of public image returned""" images = self.client.image_get_all() self.assertEqual(len(images), 2) def test_create_image_with_null_min_disk_min_ram(self): UUID3 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID3, name='asdf', min_disk=None, min_ram=None) db_api.image_create(self.context, extra_fixture) image = self.client.image_get(image_id=UUID3) self.assertEqual(0, image["min_ram"]) self.assertEqual(0, image["min_disk"]) def test_get_index_sort_name_asc(self): """ Tests that the registry API returns list of public images sorted alphabetically by name in ascending order. """ UUID3 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID3, name='asdf') db_api.image_create(self.context, extra_fixture) UUID4 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID4, name='xyz') db_api.image_create(self.context, extra_fixture) images = self.client.image_get_all(sort_key='name', sort_dir='asc') self.assertEqualImages(images, (UUID3, UUID1, UUID2, UUID4), unjsonify=False) def test_get_index_sort_status_desc(self): """ Tests that the registry API returns list of public images sorted alphabetically by status in descending order. """ uuid4_time = timeutils.utcnow() + datetime.timedelta(seconds=10) UUID3 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID3, name='asdf', status='queued') db_api.image_create(self.context, extra_fixture) UUID4 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID4, name='xyz', created_at=uuid4_time) db_api.image_create(self.context, extra_fixture) images = self.client.image_get_all(sort_key='status', sort_dir='desc') self.assertEqualImages(images, (UUID3, UUID4, UUID2, UUID1), unjsonify=False) def test_get_index_sort_disk_format_asc(self): """ Tests that the registry API returns list of public images sorted alphabetically by disk_format in ascending order. """ UUID3 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID3, name='asdf', disk_format='ami', container_format='ami') db_api.image_create(self.context, extra_fixture) UUID4 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID4, name='xyz', disk_format='vdi') db_api.image_create(self.context, extra_fixture) images = self.client.image_get_all(sort_key='disk_format', sort_dir='asc') self.assertEqualImages(images, (UUID1, UUID3, UUID4, UUID2), unjsonify=False) def test_get_index_sort_container_format_desc(self): """ Tests that the registry API returns list of public images sorted alphabetically by container_format in descending order. """ UUID3 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID3, name='asdf', disk_format='ami', container_format='ami') db_api.image_create(self.context, extra_fixture) UUID4 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID4, name='xyz', disk_format='iso', container_format='bare') db_api.image_create(self.context, extra_fixture) images = self.client.image_get_all(sort_key='container_format', sort_dir='desc') self.assertEqualImages(images, (UUID2, UUID4, UUID3, UUID1), unjsonify=False) def test_get_index_sort_size_asc(self): """ Tests that the registry API returns list of public images sorted by size in ascending order. """ UUID3 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID3, name='asdf', disk_format='ami', container_format='ami', size=100, virtual_size=200) db_api.image_create(self.context, extra_fixture) UUID4 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID4, name='asdf', disk_format='iso', container_format='bare', size=2, virtual_size=4) db_api.image_create(self.context, extra_fixture) images = self.client.image_get_all(sort_key='size', sort_dir='asc') self.assertEqualImages(images, (UUID4, UUID1, UUID2, UUID3), unjsonify=False) def test_get_index_sort_created_at_asc(self): """ Tests that the registry API returns list of public images sorted by created_at in ascending order. """ uuid4_time = timeutils.utcnow() + datetime.timedelta(seconds=10) uuid3_time = uuid4_time + datetime.timedelta(seconds=5) UUID3 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID3, created_at=uuid3_time) db_api.image_create(self.context, extra_fixture) UUID4 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID4, created_at=uuid4_time) db_api.image_create(self.context, extra_fixture) images = self.client.image_get_all(sort_key='created_at', sort_dir='asc') self.assertEqualImages(images, (UUID1, UUID2, UUID4, UUID3), unjsonify=False) def test_get_index_sort_updated_at_desc(self): """ Tests that the registry API returns list of public images sorted by updated_at in descending order. """ uuid4_time = timeutils.utcnow() + datetime.timedelta(seconds=10) uuid3_time = uuid4_time + datetime.timedelta(seconds=5) UUID3 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID3, created_at=None, updated_at=uuid3_time) db_api.image_create(self.context, extra_fixture) UUID4 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID4, created_at=None, updated_at=uuid4_time) db_api.image_create(self.context, extra_fixture) images = self.client.image_get_all(sort_key='updated_at', sort_dir='desc') self.assertEqualImages(images, (UUID3, UUID4, UUID2, UUID1), unjsonify=False) def test_image_get_index_marker(self): """Test correct set of images returned with marker param.""" uuid4_time = timeutils.utcnow() + datetime.timedelta(seconds=10) uuid3_time = uuid4_time + datetime.timedelta(seconds=5) UUID3 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID3, name='new name! #123', status='saving', created_at=uuid3_time) db_api.image_create(self.context, extra_fixture) UUID4 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID4, name='new name! #125', status='saving', created_at=uuid4_time) db_api.image_create(self.context, extra_fixture) images = self.client.image_get_all(marker=UUID3) self.assertEqualImages(images, (UUID4, UUID2, UUID1), unjsonify=False) def test_image_get_index_limit(self): """Test correct number of images returned with limit param.""" extra_fixture = self.get_fixture(id=_gen_uuid(), name='new name! #123', status='saving') db_api.image_create(self.context, extra_fixture) extra_fixture = self.get_fixture(id=_gen_uuid(), name='new name! #125', status='saving') db_api.image_create(self.context, extra_fixture) images = self.client.image_get_all(limit=2) self.assertEqual(len(images), 2) def test_image_get_index_marker_limit(self): """Test correct set of images returned with marker/limit params.""" uuid4_time = timeutils.utcnow() + datetime.timedelta(seconds=10) uuid3_time = uuid4_time + datetime.timedelta(seconds=5) UUID3 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID3, name='new name! #123', status='saving', created_at=uuid3_time) db_api.image_create(self.context, extra_fixture) UUID4 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID4, name='new name! #125', status='saving', created_at=uuid4_time) db_api.image_create(self.context, extra_fixture) images = self.client.image_get_all(marker=UUID4, limit=1) self.assertEqualImages(images, (UUID2,), unjsonify=False) def test_image_get_index_limit_None(self): """Test correct set of images returned with limit param == None.""" extra_fixture = self.get_fixture(id=_gen_uuid(), name='new name! #123', status='saving') db_api.image_create(self.context, extra_fixture) extra_fixture = self.get_fixture(id=_gen_uuid(), name='new name! #125', status='saving') db_api.image_create(self.context, extra_fixture) images = self.client.image_get_all(limit=None) self.assertEqual(len(images), 4) def test_image_get_index_by_name(self): """ Test correct set of public, name-filtered image returned. This is just a sanity check, we test the details call more in-depth. """ extra_fixture = self.get_fixture(id=_gen_uuid(), name='new name! #123') db_api.image_create(self.context, extra_fixture) images = self.client.image_get_all(filters={'name': 'new name! #123'}) self.assertEqual(len(images), 1) for image in images: self.assertEqual('new name! #123', image['name']) def test_image_get_is_public_v2(self): """Tests that a detailed call can be filtered by a property""" extra_fixture = self.get_fixture(id=_gen_uuid(), status='saving', properties={'is_public': 'avalue'}) context = copy.copy(self.context) db_api.image_create(context, extra_fixture) filters = {'is_public': 'avalue'} images = self.client.image_get_all(filters=filters) self.assertEqual(len(images), 1) for image in images: self.assertEqual('avalue', image['properties'][0]['value']) def test_image_get(self): """Tests that the detailed info about an image returned""" fixture = self.get_fixture(id=UUID1, name='fake image #1', is_public=False, size=13, virtual_size=26, disk_format='ami', container_format='ami') data = self.client.image_get(image_id=UUID1) for k, v in fixture.items(): el = data[k] self.assertEqual(v, data[k], "Failed v != data[k] where v = %(v)s and " "k = %(k)s and data[k] = %(el)s" % dict(v=v, k=k, el=el)) def test_image_get_non_existing(self): """Tests that NotFound is raised when getting a non-existing image""" self.assertRaises(exception.NotFound, self.client.image_get, image_id=_gen_uuid()) def test_image_create_basic(self): """Tests that we can add image metadata and returns the new id""" fixture = self.get_fixture() new_image = self.client.image_create(values=fixture) # Test all other attributes set data = self.client.image_get(image_id=new_image['id']) for k, v in fixture.items(): self.assertEqual(v, data[k]) # Test status was updated properly self.assertTrue('status' in data.keys()) self.assertEqual('active', data['status']) def test_image_create_with_properties(self): """Tests that we can add image metadata with properties""" fixture = self.get_fixture(location="file:///tmp/glance-tests/2", properties={'distro': 'Ubuntu 10.04 LTS'}) new_image = self.client.image_create(values=fixture) self.assertIn('properties', new_image) self.assertEqual(new_image['properties'][0]['value'], fixture['properties']['distro']) del fixture['location'] del fixture['properties'] for k, v in fixture.items(): self.assertEqual(v, new_image[k]) # Test status was updated properly self.assertTrue('status' in new_image.keys()) self.assertEqual('active', new_image['status']) def test_image_create_already_exists(self): """Tests proper exception is raised if image with ID already exists""" fixture = self.get_fixture(id=UUID2, location="file:///tmp/glance-tests/2") self.assertRaises(exception.Duplicate, self.client.image_create, values=fixture) def test_image_create_with_bad_status(self): """Tests proper exception is raised if a bad status is set""" fixture = self.get_fixture(status='bad status', location="file:///tmp/glance-tests/2") self.assertRaises(exception.Invalid, self.client.image_create, values=fixture) def test_image_update(self): """Tests that the registry API updates the image""" fixture = {'name': 'fake public image #2', 'disk_format': 'vmdk', 'status': 'saving'} self.assertTrue(self.client.image_update(image_id=UUID2, values=fixture)) # Test all other attributes set data = self.client.image_get(image_id=UUID2) for k, v in fixture.items(): self.assertEqual(v, data[k]) def test_image_update_conflict(self): """Tests that the registry API updates the image""" next_state = 'saving' fixture = {'name': 'fake public image #2', 'disk_format': 'vmdk', 'status': next_state} image = self.client.image_get(image_id=UUID2) current = image['status'] self.assertEqual(current, 'active') # image is in 'active' state so this should cause a failure. from_state = 'saving' self.assertRaises(exception.Conflict, self.client.image_update, image_id=UUID2, values=fixture, from_state=from_state) try: self.client.image_update(image_id=UUID2, values=fixture, from_state=from_state) except exception.Conflict as exc: msg = (_('cannot transition from %(current)s to ' '%(next)s in update (wanted ' 'from_state=%(from)s)') % {'current': current, 'next': next_state, 'from': from_state}) self.assertEqual(str(exc), msg) def _test_image_update_not_existing(self): """Tests non existing image update doesn't work""" fixture = self.get_fixture(status='bad status') self.assertRaises(exception.NotFound, self.client.image_update, image_id=_gen_uuid(), values=fixture) def test_image_destroy(self): """Tests that image metadata is deleted properly""" # Grab the original number of images orig_num_images = len(self.client.image_get_all()) # Delete image #2 image = self.FIXTURES[1] deleted_image = self.client.image_destroy(image_id=image['id']) self.assertTrue(deleted_image) self.assertEqual(image['id'], deleted_image['id']) self.assertTrue(deleted_image['deleted']) self.assertTrue(deleted_image['deleted_at']) # Verify one less image filters = {'deleted': False} new_num_images = len(self.client.image_get_all(filters=filters)) self.assertEqual(new_num_images, orig_num_images - 1) def test_image_destroy_not_existing(self): """Tests cannot delete non-existing image""" self.assertRaises(exception.NotFound, self.client.image_destroy, image_id=_gen_uuid()) def test_image_get_members(self): """Tests getting image members""" memb_list = self.client.image_member_find(image_id=UUID2) num_members = len(memb_list) self.assertEqual(num_members, 0) def test_image_get_members_not_existing(self): """Tests getting non-existent image members""" self.assertRaises(exception.NotFound, self.client.image_get_members, image_id=_gen_uuid()) def test_image_member_find(self): """Tests getting member images""" memb_list = self.client.image_member_find(member='pattieblack') num_members = len(memb_list) self.assertEqual(num_members, 0) def test_add_update_members(self): """Tests updating image members""" values = dict(image_id=UUID2, member='pattieblack') member = self.client.image_member_create(values=values) self.assertTrue(member) values['member'] = 'pattieblack2' self.assertTrue(self.client.image_member_update(memb_id=member['id'], values=values)) def test_add_delete_member(self): """Tests deleting image members""" values = dict(image_id=UUID2, member='pattieblack') member = self.client.image_member_create(values=values) self.client.image_member_delete(memb_id=member['id']) memb_list = self.client.image_member_find(member='pattieblack') self.assertEqual(len(memb_list), 0) class TestRegistryV2ClientApi(base.IsolatedUnitTest): """ Test proper actions made for both valid and invalid requests against a Registry service """ def setUp(self): """Establish a clean test environment""" super(TestRegistryV2ClientApi, self).setUp() self.mox = mox.Mox() reload(rapi) def tearDown(self): """Clear the test environment""" super(TestRegistryV2ClientApi, self).tearDown() self.mox.UnsetStubs() def test_configure_registry_client_not_using_use_user_token(self): self.config(use_user_token=False) self.mox.StubOutWithMock(rapi, 'configure_registry_admin_creds') rapi.configure_registry_admin_creds() self.mox.ReplayAll() rapi.configure_registry_client() self.mox.VerifyAll() def _get_fake_config_creds(self, auth_url='auth_url', strategy='keystone'): return { 'user': 'user', 'password': 'password', 'username': 'user', 'tenant': 'tenant', 'auth_url': auth_url, 'strategy': strategy, 'region': 'region' } def test_configure_registry_admin_creds(self): expected = self._get_fake_config_creds(auth_url=None, strategy='configured_strategy') self.config(admin_user=expected['user']) self.config(admin_password=expected['password']) self.config(admin_tenant_name=expected['tenant']) self.config(auth_strategy=expected['strategy']) self.config(auth_region=expected['region']) self.stubs.Set(os, 'getenv', lambda x: None) self.assertIsNone(rapi._CLIENT_CREDS) rapi.configure_registry_admin_creds() self.assertEqual(rapi._CLIENT_CREDS, expected) def test_configure_registry_admin_creds_with_auth_url(self): expected = self._get_fake_config_creds() self.config(admin_user=expected['user']) self.config(admin_password=expected['password']) self.config(admin_tenant_name=expected['tenant']) self.config(auth_url=expected['auth_url']) self.config(auth_strategy='test_strategy') self.config(auth_region=expected['region']) self.assertIsNone(rapi._CLIENT_CREDS) rapi.configure_registry_admin_creds() self.assertEqual(rapi._CLIENT_CREDS, expected) glance-2014.1/glance/tests/unit/v2/test_registry_api.py0000664000175400017540000014061212323736226024215 0ustar jenkinsjenkins00000000000000# -*- coding: utf-8 -*- # Copyright 2013 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. import datetime import uuid from oslo.config import cfg import routes import webob import glance.api.common import glance.common.config import glance.context from glance.db.sqlalchemy import api as db_api from glance.db.sqlalchemy import models as db_models from glance.openstack.common import jsonutils from glance.openstack.common import timeutils from glance.registry.api import v2 as rserver import glance.store.filesystem from glance.tests.unit import base from glance.tests import utils as test_utils CONF = cfg.CONF _gen_uuid = lambda: str(uuid.uuid4()) UUID1 = _gen_uuid() UUID2 = _gen_uuid() class TestRegistryRPC(base.IsolatedUnitTest): def setUp(self): super(TestRegistryRPC, self).setUp() self.mapper = routes.Mapper() self.api = test_utils.FakeAuthMiddleware(rserver.API(self.mapper), is_admin=True) uuid1_time = timeutils.utcnow() uuid2_time = uuid1_time + datetime.timedelta(seconds=5) self.FIXTURES = [ {'id': UUID1, 'name': 'fake image #1', 'status': 'active', 'disk_format': 'ami', 'container_format': 'ami', 'is_public': False, 'created_at': uuid1_time, 'updated_at': uuid1_time, 'deleted_at': None, 'deleted': False, 'checksum': None, 'min_disk': 0, 'min_ram': 0, 'size': 13, 'locations': [{'url': "file:///%s/%s" % (self.test_dir, UUID1), 'metadata': {}}], 'properties': {'type': 'kernel'}}, {'id': UUID2, 'name': 'fake image #2', 'status': 'active', 'disk_format': 'vhd', 'container_format': 'ovf', 'is_public': True, 'created_at': uuid2_time, 'updated_at': uuid2_time, 'deleted_at': None, 'deleted': False, 'checksum': None, 'min_disk': 5, 'min_ram': 256, 'size': 19, 'locations': [{'url': "file:///%s/%s" % (self.test_dir, UUID2), 'metadata': {}}], 'properties': {}}] self.context = glance.context.RequestContext(is_admin=True) db_api.get_engine() self.destroy_fixtures() self.create_fixtures() def tearDown(self): """Clear the test environment""" super(TestRegistryRPC, self).tearDown() self.destroy_fixtures() def create_fixtures(self): for fixture in self.FIXTURES: db_api.image_create(self.context, fixture) # We write a fake image file to the filesystem with open("%s/%s" % (self.test_dir, fixture['id']), 'wb') as image: image.write("chunk00000remainder") image.flush() def destroy_fixtures(self): # Easiest to just drop the models and re-create them... db_models.unregister_models(db_api.get_engine()) db_models.register_models(db_api.get_engine()) def test_show(self): """ Tests that registry API endpoint returns the expected image """ fixture = {'id': UUID2, 'name': 'fake image #2', 'size': 19, 'min_ram': 256, 'min_disk': 5, 'checksum': None} req = webob.Request.blank('/rpc') req.method = "POST" cmd = [{ 'command': 'image_get', 'kwargs': {'image_id': UUID2}, }] req.body = jsonutils.dumps(cmd) res = req.get_response(self.api) self.assertEqual(res.status_int, 200) res_dict = jsonutils.loads(res.body)[0] image = res_dict for k, v in fixture.iteritems(): self.assertEqual(v, image[k]) def test_show_unknown(self): """ Tests that the registry API endpoint returns a 404 for an unknown image id """ req = webob.Request.blank('/rpc') req.method = "POST" cmd = [{ 'command': 'image_get', 'kwargs': {'image_id': _gen_uuid()}, }] req.body = jsonutils.dumps(cmd) res = req.get_response(self.api) res_dict = jsonutils.loads(res.body)[0] self.assertEqual(res_dict["_error"]["cls"], 'glance.common.exception.NotFound') def test_get_index(self): """ Tests that the image_get_all command returns list of images """ fixture = {'id': UUID2, 'name': 'fake image #2', 'size': 19, 'checksum': None} req = webob.Request.blank('/rpc') req.method = "POST" cmd = [{ 'command': 'image_get_all', 'kwargs': {'filters': fixture}, }] req.body = jsonutils.dumps(cmd) res = req.get_response(self.api) self.assertEqual(res.status_int, 200) images = jsonutils.loads(res.body)[0] self.assertEqual(len(images), 1) for k, v in fixture.iteritems(): self.assertEqual(v, images[0][k]) def test_get_index_marker(self): """ Tests that the registry API returns list of public images that conforms to a marker query param """ uuid5_time = timeutils.utcnow() + datetime.timedelta(seconds=10) uuid4_time = uuid5_time + datetime.timedelta(seconds=5) uuid3_time = uuid4_time + datetime.timedelta(seconds=5) UUID3 = _gen_uuid() extra_fixture = {'id': UUID3, 'status': 'active', 'is_public': True, 'disk_format': 'vhd', 'container_format': 'ovf', 'name': 'new name! #123', 'size': 19, 'checksum': None, 'created_at': uuid3_time, 'updated_at': uuid3_time} db_api.image_create(self.context, extra_fixture) UUID4 = _gen_uuid() extra_fixture = {'id': UUID4, 'status': 'active', 'is_public': True, 'disk_format': 'vhd', 'container_format': 'ovf', 'name': 'new name! #123', 'size': 20, 'checksum': None, 'created_at': uuid4_time, 'updated_at': uuid4_time} db_api.image_create(self.context, extra_fixture) UUID5 = _gen_uuid() extra_fixture = {'id': UUID5, 'status': 'active', 'is_public': True, 'disk_format': 'vhd', 'container_format': 'ovf', 'name': 'new name! #123', 'size': 20, 'checksum': None, 'created_at': uuid5_time, 'updated_at': uuid5_time} db_api.image_create(self.context, extra_fixture) req = webob.Request.blank('/rpc') req.method = "POST" cmd = [{ 'command': 'image_get_all', 'kwargs': {'marker': UUID4, "is_public": True}, }] req.body = jsonutils.dumps(cmd) res = req.get_response(self.api) self.assertEqual(res.status_int, 200) images = jsonutils.loads(res.body)[0] # should be sorted by created_at desc, id desc # page should start after marker 4 self.assertEqual(len(images), 2) self.assertEqual(images[0]['id'], UUID5) self.assertEqual(images[1]['id'], UUID2) def test_get_index_marker_and_name_asc(self): """Test marker and null name ascending Tests that the registry API returns 200 when a marker and a null name are combined ascending order """ UUID3 = _gen_uuid() extra_fixture = {'id': UUID3, 'status': 'active', 'is_public': True, 'disk_format': 'vhd', 'container_format': 'ovf', 'name': None, 'size': 19, 'checksum': None} db_api.image_create(self.context, extra_fixture) req = webob.Request.blank('/rpc') req.method = "POST" cmd = [{ 'command': 'image_get_all', 'kwargs': {'marker': UUID3, 'sort_key': 'name', 'sort_dir': 'asc'}, }] req.body = jsonutils.dumps(cmd) res = req.get_response(self.api) self.assertEqual(res.status_int, 200) images = jsonutils.loads(res.body)[0] self.assertEqual(len(images), 2) def test_get_index_marker_and_name_desc(self): """Test marker and null name descending Tests that the registry API returns 200 when a marker and a null name are combined descending order """ UUID3 = _gen_uuid() extra_fixture = {'id': UUID3, 'status': 'active', 'is_public': True, 'disk_format': 'vhd', 'container_format': 'ovf', 'name': None, 'size': 19, 'checksum': None} db_api.image_create(self.context, extra_fixture) req = webob.Request.blank('/rpc') req.method = "POST" cmd = [{ 'command': 'image_get_all', 'kwargs': {'marker': UUID3, 'sort_key': 'name', 'sort_dir': 'desc'}, }] req.body = jsonutils.dumps(cmd) res = req.get_response(self.api) self.assertEqual(res.status_int, 200) images = jsonutils.loads(res.body)[0] self.assertEqual(len(images), 0) def test_get_index_marker_and_disk_format_asc(self): """Test marker and null disk format ascending Tests that the registry API returns 200 when a marker and a null disk_format are combined ascending order """ UUID3 = _gen_uuid() extra_fixture = {'id': UUID3, 'status': 'active', 'is_public': True, 'disk_format': None, 'container_format': 'ovf', 'name': 'Fake image', 'size': 19, 'checksum': None} db_api.image_create(self.context, extra_fixture) req = webob.Request.blank('/rpc') req.method = "POST" cmd = [{ 'command': 'image_get_all', 'kwargs': {'marker': UUID3, 'sort_key': 'disk_format', 'sort_dir': 'asc'}, }] req.body = jsonutils.dumps(cmd) res = req.get_response(self.api) self.assertEqual(res.status_int, 200) images = jsonutils.loads(res.body)[0] self.assertEqual(len(images), 2) def test_get_index_marker_and_disk_format_desc(self): """Test marker and null disk format descending Tests that the registry API returns 200 when a marker and a null disk_format are combined descending order """ UUID3 = _gen_uuid() extra_fixture = {'id': UUID3, 'status': 'active', 'is_public': True, 'disk_format': None, 'container_format': 'ovf', 'name': 'Fake image', 'size': 19, 'checksum': None} db_api.image_create(self.context, extra_fixture) req = webob.Request.blank('/rpc') req.method = "POST" cmd = [{ 'command': 'image_get_all', 'kwargs': {'marker': UUID3, 'sort_key': 'disk_format', 'sort_dir': 'desc'}, }] req.body = jsonutils.dumps(cmd) res = req.get_response(self.api) self.assertEqual(res.status_int, 200) images = jsonutils.loads(res.body)[0] self.assertEqual(len(images), 0) def test_get_index_marker_and_container_format_asc(self): """Test marker and null container format ascending Tests that the registry API returns 200 when a marker and a null container_format are combined ascending order """ UUID3 = _gen_uuid() extra_fixture = {'id': UUID3, 'status': 'active', 'is_public': True, 'disk_format': 'vhd', 'container_format': None, 'name': 'Fake image', 'size': 19, 'checksum': None} db_api.image_create(self.context, extra_fixture) req = webob.Request.blank('/rpc') req.method = "POST" cmd = [{ 'command': 'image_get_all', 'kwargs': {'marker': UUID3, 'sort_key': 'container_format', 'sort_dir': 'asc'}, }] req.body = jsonutils.dumps(cmd) res = req.get_response(self.api) self.assertEqual(res.status_int, 200) images = jsonutils.loads(res.body)[0] self.assertEqual(len(images), 2) def test_get_index_marker_and_container_format_desc(self): """Test marker and null container format descending Tests that the registry API returns 200 when a marker and a null container_format are combined descending order """ UUID3 = _gen_uuid() extra_fixture = {'id': UUID3, 'status': 'active', 'is_public': True, 'disk_format': 'vhd', 'container_format': None, 'name': 'Fake image', 'size': 19, 'checksum': None} db_api.image_create(self.context, extra_fixture) req = webob.Request.blank('/rpc') req.method = "POST" cmd = [{ 'command': 'image_get_all', 'kwargs': {'marker': UUID3, 'sort_key': 'container_format', 'sort_dir': 'desc'}, }] req.body = jsonutils.dumps(cmd) res = req.get_response(self.api) self.assertEqual(res.status_int, 200) images = jsonutils.loads(res.body)[0] self.assertEqual(len(images), 0) def test_get_index_unknown_marker(self): """ Tests that the registry API returns a NotFound when an unknown marker is provided """ req = webob.Request.blank('/rpc') req.method = "POST" cmd = [{ 'command': 'image_get_all', 'kwargs': {'marker': _gen_uuid()}, }] req.body = jsonutils.dumps(cmd) res = req.get_response(self.api) result = jsonutils.loads(res.body)[0] self.assertIn("_error", result) self.assertIn("NotFound", result["_error"]["cls"]) def test_get_index_limit(self): """ Tests that the registry API returns list of public images that conforms to a limit query param """ uuid3_time = timeutils.utcnow() + datetime.timedelta(seconds=10) uuid4_time = uuid3_time + datetime.timedelta(seconds=5) UUID3 = _gen_uuid() extra_fixture = {'id': UUID3, 'status': 'active', 'is_public': True, 'disk_format': 'vhd', 'container_format': 'ovf', 'name': 'new name! #123', 'size': 19, 'checksum': None, 'created_at': uuid3_time, 'updated_at': uuid3_time} db_api.image_create(self.context, extra_fixture) UUID4 = _gen_uuid() extra_fixture = {'id': UUID4, 'status': 'active', 'is_public': True, 'disk_format': 'vhd', 'container_format': 'ovf', 'name': 'new name! #123', 'size': 20, 'checksum': None, 'created_at': uuid4_time, 'updated_at': uuid4_time} db_api.image_create(self.context, extra_fixture) req = webob.Request.blank('/rpc') req.method = "POST" cmd = [{ 'command': 'image_get_all', 'kwargs': {'limit': 1}, }] req.body = jsonutils.dumps(cmd) res = req.get_response(self.api) res_dict = jsonutils.loads(res.body)[0] self.assertEqual(res.status_int, 200) images = res_dict self.assertEqual(len(images), 1) # expect list to be sorted by created_at desc self.assertEqual(images[0]['id'], UUID4) def test_get_index_limit_marker(self): """ Tests that the registry API returns list of public images that conforms to limit and marker query params """ uuid3_time = timeutils.utcnow() + datetime.timedelta(seconds=10) uuid4_time = uuid3_time + datetime.timedelta(seconds=5) UUID3 = _gen_uuid() extra_fixture = {'id': UUID3, 'status': 'active', 'is_public': True, 'disk_format': 'vhd', 'container_format': 'ovf', 'name': 'new name! #123', 'size': 19, 'checksum': None, 'created_at': uuid3_time, 'updated_at': uuid3_time} db_api.image_create(self.context, extra_fixture) extra_fixture = {'id': _gen_uuid(), 'status': 'active', 'is_public': True, 'disk_format': 'vhd', 'container_format': 'ovf', 'name': 'new name! #123', 'size': 20, 'checksum': None, 'created_at': uuid4_time, 'updated_at': uuid4_time} db_api.image_create(self.context, extra_fixture) req = webob.Request.blank('/rpc') req.method = "POST" cmd = [{ 'command': 'image_get_all', 'kwargs': {'marker': UUID3, 'limit': 1}, }] req.body = jsonutils.dumps(cmd) res = req.get_response(self.api) res_dict = jsonutils.loads(res.body)[0] self.assertEqual(res.status_int, 200) images = res_dict self.assertEqual(len(images), 1) # expect list to be sorted by created_at desc self.assertEqual(images[0]['id'], UUID2) def test_get_index_filter_name(self): """ Tests that the registry API returns list of public images that have a specific name. This is really a sanity check, filtering is tested more in-depth using /images/detail """ extra_fixture = {'id': _gen_uuid(), 'status': 'active', 'is_public': True, 'disk_format': 'vhd', 'container_format': 'ovf', 'name': 'new name! #123', 'size': 19, 'checksum': None} db_api.image_create(self.context, extra_fixture) extra_fixture = {'id': _gen_uuid(), 'status': 'active', 'is_public': True, 'disk_format': 'vhd', 'container_format': 'ovf', 'name': 'new name! #123', 'size': 20, 'checksum': None} db_api.image_create(self.context, extra_fixture) req = webob.Request.blank('/rpc') req.method = "POST" cmd = [{ 'command': 'image_get_all', 'kwargs': {'filters': {'name': 'new name! #123'}}, }] req.body = jsonutils.dumps(cmd) res = req.get_response(self.api) res_dict = jsonutils.loads(res.body)[0] self.assertEqual(res.status_int, 200) images = res_dict self.assertEqual(len(images), 2) for image in images: self.assertEqual('new name! #123', image['name']) def test_get_index_filter_on_user_defined_properties(self): """ Tests that the registry API returns list of public images that have a specific user-defined properties. """ properties = {'distro': 'ubuntu', 'arch': 'i386', 'type': 'kernel'} extra_id = _gen_uuid() extra_fixture = {'id': extra_id, 'status': 'active', 'is_public': True, 'disk_format': 'vhd', 'container_format': 'ovf', 'name': 'image-extra-1', 'size': 19, 'properties': properties, 'checksum': None} db_api.image_create(self.context, extra_fixture) # testing with a common property. req = webob.Request.blank('/rpc') req.method = "POST" cmd = [{ 'command': 'image_get_all', 'kwargs': {'filters': {'type': 'kernel'}}, }] req.body = jsonutils.dumps(cmd) res = req.get_response(self.api) self.assertEqual(res.status_int, 200) images = jsonutils.loads(res.body)[0] self.assertEqual(len(images), 2) self.assertEqual(images[0]['id'], extra_id) self.assertEqual(images[1]['id'], UUID1) # testing with a non-existent value for a common property. cmd = [{ 'command': 'image_get_all', 'kwargs': {'filters': {'type': 'random'}}, }] req.body = jsonutils.dumps(cmd) res = req.get_response(self.api) self.assertEqual(res.status_int, 200) images = jsonutils.loads(res.body)[0] self.assertEqual(len(images), 0) # testing with a non-existent value for a common property. cmd = [{ 'command': 'image_get_all', 'kwargs': {'filters': {'type': 'random'}}, }] req.body = jsonutils.dumps(cmd) res = req.get_response(self.api) self.assertEqual(res.status_int, 200) images = jsonutils.loads(res.body)[0] self.assertEqual(len(images), 0) # testing with a non-existent property. cmd = [{ 'command': 'image_get_all', 'kwargs': {'filters': {'poo': 'random'}}, }] req.body = jsonutils.dumps(cmd) res = req.get_response(self.api) self.assertEqual(res.status_int, 200) images = jsonutils.loads(res.body)[0] self.assertEqual(len(images), 0) # testing with multiple existing properties. cmd = [{ 'command': 'image_get_all', 'kwargs': {'filters': {'type': 'kernel', 'distro': 'ubuntu'}}, }] req.body = jsonutils.dumps(cmd) res = req.get_response(self.api) self.assertEqual(res.status_int, 200) images = jsonutils.loads(res.body)[0] self.assertEqual(len(images), 1) self.assertEqual(images[0]['id'], extra_id) # testing with multiple existing properties but non-existent values. cmd = [{ 'command': 'image_get_all', 'kwargs': {'filters': {'type': 'random', 'distro': 'random'}}, }] req.body = jsonutils.dumps(cmd) res = req.get_response(self.api) self.assertEqual(res.status_int, 200) images = jsonutils.loads(res.body)[0] self.assertEqual(len(images), 0) # testing with multiple non-existing properties. cmd = [{ 'command': 'image_get_all', 'kwargs': {'filters': {'typo': 'random', 'poo': 'random'}}, }] req.body = jsonutils.dumps(cmd) res = req.get_response(self.api) self.assertEqual(res.status_int, 200) images = jsonutils.loads(res.body)[0] self.assertEqual(len(images), 0) # testing with one existing property and the other non-existing. cmd = [{ 'command': 'image_get_all', 'kwargs': {'filters': {'type': 'kernel', 'poo': 'random'}}, }] req.body = jsonutils.dumps(cmd) res = req.get_response(self.api) self.assertEqual(res.status_int, 200) images = jsonutils.loads(res.body)[0] self.assertEqual(len(images), 0) def test_get_index_sort_default_created_at_desc(self): """ Tests that the registry API returns list of public images that conforms to a default sort key/dir """ uuid5_time = timeutils.utcnow() + datetime.timedelta(seconds=10) uuid4_time = uuid5_time + datetime.timedelta(seconds=5) uuid3_time = uuid4_time + datetime.timedelta(seconds=5) UUID3 = _gen_uuid() extra_fixture = {'id': UUID3, 'status': 'active', 'is_public': True, 'disk_format': 'vhd', 'container_format': 'ovf', 'name': 'new name! #123', 'size': 19, 'checksum': None, 'created_at': uuid3_time, 'updated_at': uuid3_time} db_api.image_create(self.context, extra_fixture) UUID4 = _gen_uuid() extra_fixture = {'id': UUID4, 'status': 'active', 'is_public': True, 'disk_format': 'vhd', 'container_format': 'ovf', 'name': 'new name! #123', 'size': 20, 'checksum': None, 'created_at': uuid4_time, 'updated_at': uuid4_time} db_api.image_create(self.context, extra_fixture) UUID5 = _gen_uuid() extra_fixture = {'id': UUID5, 'status': 'active', 'is_public': True, 'disk_format': 'vhd', 'container_format': 'ovf', 'name': 'new name! #123', 'size': 20, 'checksum': None, 'created_at': uuid5_time, 'updated_at': uuid5_time} db_api.image_create(self.context, extra_fixture) req = webob.Request.blank('/rpc') req.method = "POST" cmd = [{ 'command': 'image_get_all', }] req.body = jsonutils.dumps(cmd) res = req.get_response(self.api) res_dict = jsonutils.loads(res.body)[0] self.assertEqual(res.status_int, 200) images = res_dict # (flaper87)registry's v1 forced is_public to True # when no value was specified. This is not # the default behaviour anymore. self.assertEqual(len(images), 5) self.assertEqual(images[0]['id'], UUID3) self.assertEqual(images[1]['id'], UUID4) self.assertEqual(images[2]['id'], UUID5) self.assertEqual(images[3]['id'], UUID2) self.assertEqual(images[4]['id'], UUID1) def test_get_index_sort_name_asc(self): """ Tests that the registry API returns list of public images sorted alphabetically by name in ascending order. """ UUID3 = _gen_uuid() extra_fixture = {'id': UUID3, 'status': 'active', 'is_public': True, 'disk_format': 'vhd', 'container_format': 'ovf', 'name': 'asdf', 'size': 19, 'checksum': None} db_api.image_create(self.context, extra_fixture) UUID4 = _gen_uuid() extra_fixture = {'id': UUID4, 'status': 'active', 'is_public': True, 'disk_format': 'vhd', 'container_format': 'ovf', 'name': 'xyz', 'size': 20, 'checksum': None} db_api.image_create(self.context, extra_fixture) UUID5 = _gen_uuid() extra_fixture = {'id': UUID5, 'status': 'active', 'is_public': True, 'disk_format': 'vhd', 'container_format': 'ovf', 'name': None, 'size': 20, 'checksum': None} db_api.image_create(self.context, extra_fixture) req = webob.Request.blank('/rpc') req.method = "POST" cmd = [{ 'command': 'image_get_all', 'kwargs': {'sort_key': 'name', 'sort_dir': 'asc'} }] req.body = jsonutils.dumps(cmd) res = req.get_response(self.api) self.assertEqual(res.status_int, 200) res_dict = jsonutils.loads(res.body)[0] images = res_dict self.assertEqual(len(images), 5) self.assertEqual(images[0]['id'], UUID5) self.assertEqual(images[1]['id'], UUID3) self.assertEqual(images[2]['id'], UUID1) self.assertEqual(images[3]['id'], UUID2) self.assertEqual(images[4]['id'], UUID4) def test_get_index_sort_status_desc(self): """ Tests that the registry API returns list of public images sorted alphabetically by status in descending order. """ uuid4_time = timeutils.utcnow() + datetime.timedelta(seconds=10) UUID3 = _gen_uuid() extra_fixture = {'id': UUID3, 'status': 'queued', 'is_public': True, 'disk_format': 'vhd', 'container_format': 'ovf', 'name': 'asdf', 'size': 19, 'checksum': None} db_api.image_create(self.context, extra_fixture) UUID4 = _gen_uuid() extra_fixture = {'id': UUID4, 'status': 'active', 'is_public': True, 'disk_format': 'vhd', 'container_format': 'ovf', 'name': 'xyz', 'size': 20, 'checksum': None, 'created_at': uuid4_time, 'updated_at': uuid4_time} db_api.image_create(self.context, extra_fixture) req = webob.Request.blank('/rpc') req.method = "POST" cmd = [{ 'command': 'image_get_all', 'kwargs': {'sort_key': 'status', 'sort_dir': 'asc'} }] req.body = jsonutils.dumps(cmd) res = req.get_response(self.api) self.assertEqual(res.status_int, 200) res_dict = jsonutils.loads(res.body)[0] images = res_dict self.assertEqual(len(images), 4) self.assertEqual(images[0]['id'], UUID1) self.assertEqual(images[1]['id'], UUID2) self.assertEqual(images[2]['id'], UUID4) self.assertEqual(images[3]['id'], UUID3) def test_get_index_sort_disk_format_asc(self): """ Tests that the registry API returns list of public images sorted alphabetically by disk_format in ascending order. """ uuid3_time = timeutils.utcnow() + datetime.timedelta(seconds=5) UUID3 = _gen_uuid() extra_fixture = {'id': UUID3, 'status': 'active', 'is_public': True, 'disk_format': 'ami', 'container_format': 'ami', 'name': 'asdf', 'size': 19, 'checksum': None, 'created_at': uuid3_time, 'updated_at': uuid3_time} db_api.image_create(self.context, extra_fixture) UUID4 = _gen_uuid() extra_fixture = {'id': UUID4, 'status': 'active', 'is_public': True, 'disk_format': 'vdi', 'container_format': 'ovf', 'name': 'xyz', 'size': 20, 'checksum': None} db_api.image_create(self.context, extra_fixture) req = webob.Request.blank('/rpc') req.method = "POST" cmd = [{ 'command': 'image_get_all', 'kwargs': {'sort_key': 'disk_format', 'sort_dir': 'asc'} }] req.body = jsonutils.dumps(cmd) res = req.get_response(self.api) self.assertEqual(res.status_int, 200) res_dict = jsonutils.loads(res.body)[0] images = res_dict self.assertEqual(len(images), 4) self.assertEqual(images[0]['id'], UUID1) self.assertEqual(images[1]['id'], UUID3) self.assertEqual(images[2]['id'], UUID4) self.assertEqual(images[3]['id'], UUID2) def test_get_index_sort_container_format_desc(self): """ Tests that the registry API returns list of public images sorted alphabetically by container_format in descending order. """ uuid3_time = timeutils.utcnow() + datetime.timedelta(seconds=5) UUID3 = _gen_uuid() extra_fixture = {'id': UUID3, 'status': 'active', 'is_public': True, 'disk_format': 'ami', 'container_format': 'ami', 'name': 'asdf', 'size': 19, 'checksum': None, 'created_at': uuid3_time, 'updated_at': uuid3_time} db_api.image_create(self.context, extra_fixture) UUID4 = _gen_uuid() extra_fixture = {'id': UUID4, 'status': 'active', 'is_public': True, 'disk_format': 'iso', 'container_format': 'bare', 'name': 'xyz', 'size': 20, 'checksum': None} db_api.image_create(self.context, extra_fixture) req = webob.Request.blank('/rpc') req.method = "POST" cmd = [{ 'command': 'image_get_all', 'kwargs': {'sort_key': 'container_format', 'sort_dir': 'desc'} }] req.body = jsonutils.dumps(cmd) res = req.get_response(self.api) self.assertEqual(res.status_int, 200) res_dict = jsonutils.loads(res.body)[0] images = res_dict self.assertEqual(len(images), 4) self.assertEqual(images[0]['id'], UUID2) self.assertEqual(images[1]['id'], UUID4) self.assertEqual(images[2]['id'], UUID3) self.assertEqual(images[3]['id'], UUID1) def test_get_index_sort_size_asc(self): """ Tests that the registry API returns list of public images sorted by size in ascending order. """ UUID3 = _gen_uuid() extra_fixture = {'id': UUID3, 'status': 'active', 'is_public': True, 'disk_format': 'ami', 'container_format': 'ami', 'name': 'asdf', 'size': 100, 'checksum': None} db_api.image_create(self.context, extra_fixture) UUID4 = _gen_uuid() extra_fixture = {'id': UUID4, 'status': 'active', 'is_public': True, 'disk_format': 'iso', 'container_format': 'bare', 'name': 'xyz', 'size': 2, 'checksum': None} db_api.image_create(self.context, extra_fixture) req = webob.Request.blank('/rpc') req.method = "POST" cmd = [{ 'command': 'image_get_all', 'kwargs': {'sort_key': 'size', 'sort_dir': 'asc'} }] req.body = jsonutils.dumps(cmd) res = req.get_response(self.api) self.assertEqual(res.status_int, 200) res_dict = jsonutils.loads(res.body)[0] images = res_dict self.assertEqual(len(images), 4) self.assertEqual(images[0]['id'], UUID4) self.assertEqual(images[1]['id'], UUID1) self.assertEqual(images[2]['id'], UUID2) self.assertEqual(images[3]['id'], UUID3) def test_get_index_sort_created_at_asc(self): """ Tests that the registry API returns list of public images sorted by created_at in ascending order. """ uuid4_time = timeutils.utcnow() + datetime.timedelta(seconds=10) uuid3_time = uuid4_time + datetime.timedelta(seconds=5) UUID3 = _gen_uuid() extra_fixture = {'id': UUID3, 'status': 'active', 'is_public': True, 'disk_format': 'vhd', 'container_format': 'ovf', 'name': 'new name! #123', 'size': 19, 'checksum': None, 'created_at': uuid3_time, 'updated_at': uuid3_time} db_api.image_create(self.context, extra_fixture) UUID4 = _gen_uuid() extra_fixture = {'id': UUID4, 'status': 'active', 'is_public': True, 'disk_format': 'vhd', 'container_format': 'ovf', 'name': 'new name! #123', 'size': 20, 'checksum': None, 'created_at': uuid4_time, 'updated_at': uuid4_time} db_api.image_create(self.context, extra_fixture) req = webob.Request.blank('/rpc') req.method = "POST" cmd = [{ 'command': 'image_get_all', 'kwargs': {'sort_key': 'created_at', 'sort_dir': 'asc'} }] req.body = jsonutils.dumps(cmd) res = req.get_response(self.api) self.assertEqual(res.status_int, 200) res_dict = jsonutils.loads(res.body)[0] images = res_dict self.assertEqual(len(images), 4) self.assertEqual(images[0]['id'], UUID1) self.assertEqual(images[1]['id'], UUID2) self.assertEqual(images[2]['id'], UUID4) self.assertEqual(images[3]['id'], UUID3) def test_get_index_sort_updated_at_desc(self): """ Tests that the registry API returns list of public images sorted by updated_at in descending order. """ uuid4_time = timeutils.utcnow() + datetime.timedelta(seconds=10) uuid3_time = uuid4_time + datetime.timedelta(seconds=5) UUID3 = _gen_uuid() extra_fixture = {'id': UUID3, 'status': 'active', 'is_public': True, 'disk_format': 'vhd', 'container_format': 'ovf', 'name': 'new name! #123', 'size': 19, 'checksum': None, 'created_at': None, 'updated_at': uuid3_time} db_api.image_create(self.context, extra_fixture) UUID4 = _gen_uuid() extra_fixture = {'id': UUID4, 'status': 'active', 'is_public': True, 'disk_format': 'vhd', 'container_format': 'ovf', 'name': 'new name! #123', 'size': 20, 'checksum': None, 'created_at': None, 'updated_at': uuid4_time} db_api.image_create(self.context, extra_fixture) req = webob.Request.blank('/rpc') req.method = "POST" cmd = [{ 'command': 'image_get_all', 'kwargs': {'sort_key': 'updated_at', 'sort_dir': 'desc'} }] req.body = jsonutils.dumps(cmd) res = req.get_response(self.api) self.assertEqual(res.status_int, 200) res_dict = jsonutils.loads(res.body)[0] images = res_dict self.assertEqual(len(images), 4) self.assertEqual(images[0]['id'], UUID3) self.assertEqual(images[1]['id'], UUID4) self.assertEqual(images[2]['id'], UUID2) self.assertEqual(images[3]['id'], UUID1) def test_create_image(self): """Tests that the registry API creates the image""" fixture = {'name': 'fake public image', 'status': 'active', 'is_public': True, 'disk_format': 'vhd', 'container_format': 'ovf'} req = webob.Request.blank('/rpc') req.method = "POST" cmd = [{ 'command': 'image_create', 'kwargs': {'values': fixture} }] req.body = jsonutils.dumps(cmd) res = req.get_response(self.api) self.assertEqual(res.status_int, 200) res_dict = jsonutils.loads(res.body)[0] for k, v in fixture.iteritems(): self.assertEqual(v, res_dict[k]) # Test status was updated properly self.assertEqual('active', res_dict['status']) def test_create_image_with_min_disk(self): """Tests that the registry API creates the image""" fixture = {'name': 'fake public image', 'is_public': True, 'status': 'active', 'min_disk': 5, 'disk_format': 'vhd', 'container_format': 'ovf'} req = webob.Request.blank('/rpc') req.method = "POST" cmd = [{ 'command': 'image_create', 'kwargs': {'values': fixture} }] req.body = jsonutils.dumps(cmd) res = req.get_response(self.api) self.assertEqual(res.status_int, 200) res_dict = jsonutils.loads(res.body)[0] self.assertEqual(5, res_dict['min_disk']) def test_create_image_with_min_ram(self): """Tests that the registry API creates the image""" fixture = {'name': 'fake public image', 'is_public': True, 'status': 'active', 'min_ram': 256, 'disk_format': 'vhd', 'container_format': 'ovf'} req = webob.Request.blank('/rpc') req.method = "POST" cmd = [{ 'command': 'image_create', 'kwargs': {'values': fixture} }] req.body = jsonutils.dumps(cmd) res = req.get_response(self.api) self.assertEqual(res.status_int, 200) res_dict = jsonutils.loads(res.body)[0] self.assertEqual(256, res_dict['min_ram']) def test_create_image_with_min_ram_default(self): """Tests that the registry API creates the image""" fixture = {'name': 'fake public image', 'status': 'active', 'is_public': True, 'disk_format': 'vhd', 'container_format': 'ovf'} req = webob.Request.blank('/rpc') req.method = "POST" cmd = [{ 'command': 'image_create', 'kwargs': {'values': fixture} }] req.body = jsonutils.dumps(cmd) res = req.get_response(self.api) self.assertEqual(res.status_int, 200) res_dict = jsonutils.loads(res.body)[0] self.assertEqual(0, res_dict['min_ram']) def test_create_image_with_min_disk_default(self): """Tests that the registry API creates the image""" fixture = {'name': 'fake public image', 'status': 'active', 'is_public': True, 'disk_format': 'vhd', 'container_format': 'ovf'} req = webob.Request.blank('/rpc') req.method = "POST" cmd = [{ 'command': 'image_create', 'kwargs': {'values': fixture} }] req.body = jsonutils.dumps(cmd) res = req.get_response(self.api) self.assertEqual(res.status_int, 200) res_dict = jsonutils.loads(res.body)[0] self.assertEqual(0, res_dict['min_disk']) def test_update_image(self): """Tests that the registry API updates the image""" fixture = {'name': 'fake public image #2', 'min_disk': 5, 'min_ram': 256, 'disk_format': 'raw'} req = webob.Request.blank('/rpc') req.method = "POST" cmd = [{ 'command': 'image_update', 'kwargs': {'values': fixture, 'image_id': UUID2} }] req.body = jsonutils.dumps(cmd) res = req.get_response(self.api) self.assertEqual(res.status_int, 200) res_dict = jsonutils.loads(res.body)[0] self.assertNotEqual(res_dict['created_at'], res_dict['updated_at']) for k, v in fixture.iteritems(): self.assertEqual(v, res_dict[k]) def test_delete_image(self): """Tests that the registry API deletes the image""" # Grab the original number of images req = webob.Request.blank('/rpc') req.method = "POST" cmd = [{ 'command': 'image_get_all', 'kwargs': {'filters': {'deleted': False}} }] req.body = jsonutils.dumps(cmd) res = req.get_response(self.api) res_dict = jsonutils.loads(res.body)[0] self.assertEqual(res.status_int, 200) orig_num_images = len(res_dict) # Delete image #2 cmd = [{ 'command': 'image_destroy', 'kwargs': {'image_id': UUID2} }] req.body = jsonutils.dumps(cmd) res = req.get_response(self.api) self.assertEqual(res.status_int, 200) # Verify one less image cmd = [{ 'command': 'image_get_all', 'kwargs': {'filters': {'deleted': False}} }] req.body = jsonutils.dumps(cmd) res = req.get_response(self.api) res_dict = jsonutils.loads(res.body)[0] self.assertEqual(res.status_int, 200) new_num_images = len(res_dict) self.assertEqual(new_num_images, orig_num_images - 1) def test_delete_image_response(self): """Tests that the registry API delete returns the image metadata""" image = self.FIXTURES[0] req = webob.Request.blank('/rpc') req.method = 'POST' cmd = [{ 'command': 'image_destroy', 'kwargs': {'image_id': image['id']} }] req.body = jsonutils.dumps(cmd) res = req.get_response(self.api) self.assertEqual(res.status_int, 200) deleted_image = jsonutils.loads(res.body)[0] self.assertEqual(image['id'], deleted_image['id']) self.assertTrue(deleted_image['deleted']) self.assertTrue(deleted_image['deleted_at']) def test_get_image_members(self): """ Tests members listing for existing images """ req = webob.Request.blank('/rpc') req.method = 'POST' cmd = [{ 'command': 'image_member_find', 'kwargs': {'image_id': UUID2} }] req.body = jsonutils.dumps(cmd) res = req.get_response(self.api) self.assertEqual(res.status_int, 200) memb_list = jsonutils.loads(res.body)[0] self.assertEqual(len(memb_list), 0) glance-2014.1/glance/tests/unit/v2/test_image_members_resource.py0000664000175400017540000005374512323736226026231 0ustar jenkinsjenkins00000000000000# Copyright 2013 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import datetime from oslo.config import cfg import webob import glance.api.v2.image_members from glance.openstack.common import jsonutils import glance.tests.unit.utils as unit_test_utils import glance.tests.utils as test_utils DATETIME = datetime.datetime(2012, 5, 16, 15, 27, 36, 325355) ISOTIME = '2012-05-16T15:27:36Z' CONF = cfg.CONF BASE_URI = unit_test_utils.BASE_URI UUID1 = 'c80a1a6c-bd1f-41c5-90ee-81afedb1d58d' UUID2 = 'a85abd86-55b3-4d5b-b0b4-5d0a6e6042fc' UUID3 = '971ec09a-8067-4bc8-a91f-ae3557f1c4c7' UUID4 = '6bbe7cc2-eae7-4c0f-b50d-a7160b0c6a86' UUID5 = '3eee7cc2-eae7-4c0f-b50d-a7160b0c62ed' TENANT1 = '6838eb7b-6ded-434a-882c-b344c77fe8df' TENANT2 = '2c014f32-55eb-467d-8fcb-4bd706012f81' TENANT3 = '5a3e60e8-cfa9-4a9e-a90a-62b42cea92b8' TENANT4 = 'c6c87f25-8a94-47ed-8c83-053c25f42df4' def _db_fixture(id, **kwargs): obj = { 'id': id, 'name': None, 'is_public': False, 'properties': {}, 'checksum': None, 'owner': None, 'status': 'queued', 'tags': [], 'size': None, 'locations': [], 'protected': False, 'disk_format': None, 'container_format': None, 'deleted': False, 'min_ram': None, 'min_disk': None, } obj.update(kwargs) return obj def _db_image_member_fixture(image_id, member_id, **kwargs): obj = { 'image_id': image_id, 'member': member_id, 'status': 'pending', } obj.update(kwargs) return obj def _domain_fixture(id, **kwargs): properties = { 'id': id, } properties.update(kwargs) return glance.domain.ImageMembership(**properties) class TestImageMembersController(test_utils.BaseTestCase): def setUp(self): super(TestImageMembersController, self).setUp() self.db = unit_test_utils.FakeDB() self.store = unit_test_utils.FakeStoreAPI() self.policy = unit_test_utils.FakePolicyEnforcer() self.notifier = unit_test_utils.FakeNotifier() self._create_images() self._create_image_members() self.controller = glance.api.v2.image_members\ .ImageMembersController(self.db, self.policy, self.notifier, self.store) glance.store.create_stores() def _create_images(self): self.db.reset() self.images = [ _db_fixture(UUID1, owner=TENANT1, name='1', size=256, is_public=True, locations=[{'url': '%s/%s' % (BASE_URI, UUID1), 'metadata': {}}]), _db_fixture(UUID2, owner=TENANT1, name='2', size=512), _db_fixture(UUID3, owner=TENANT3, name='3', size=512), _db_fixture(UUID4, owner=TENANT4, name='4', size=1024), _db_fixture(UUID5, owner=TENANT1, name='5', size=1024), ] [self.db.image_create(None, image) for image in self.images] self.db.image_tag_set_all(None, UUID1, ['ping', 'pong']) def _create_image_members(self): self.image_members = [ _db_image_member_fixture(UUID2, TENANT4), _db_image_member_fixture(UUID3, TENANT4), _db_image_member_fixture(UUID3, TENANT2), _db_image_member_fixture(UUID4, TENANT1), ] [self.db.image_member_create(None, image_member) for image_member in self.image_members] def test_index(self): request = unit_test_utils.get_fake_request() output = self.controller.index(request, UUID2) self.assertEqual(1, len(output['members'])) actual = set([image_member.member_id for image_member in output['members']]) expected = set([TENANT4]) self.assertEqual(actual, expected) def test_index_no_members(self): request = unit_test_utils.get_fake_request() output = self.controller.index(request, UUID5) self.assertEqual(0, len(output['members'])) self.assertEqual({'members': []}, output) def test_index_member_view(self): # UUID3 is a private image owned by TENANT3 # UUID3 has members TENANT2 and TENANT4 # When TENANT4 lists members for UUID3, should not see TENANT2 request = unit_test_utils.get_fake_request(tenant=TENANT4) output = self.controller.index(request, UUID3) self.assertEqual(1, len(output['members'])) actual = set([image_member.member_id for image_member in output['members']]) expected = set([TENANT4]) self.assertEqual(actual, expected) def test_index_private_image(self): request = unit_test_utils.get_fake_request(tenant=TENANT2) self.assertRaises(webob.exc.HTTPNotFound, self.controller.index, request, UUID5) def test_index_public_image(self): request = unit_test_utils.get_fake_request() self.assertRaises(webob.exc.HTTPForbidden, self.controller.index, request, UUID1) def test_index_private_image_visible_members_admin(self): request = unit_test_utils.get_fake_request(is_admin=True) output = self.controller.index(request, UUID4) self.assertEqual(1, len(output['members'])) actual = set([image_member.member_id for image_member in output['members']]) expected = set([TENANT1]) self.assertEqual(actual, expected) def test_index_allowed_by_get_members_policy(self): rules = {"get_members": True} self.policy.set_rules(rules) request = unit_test_utils.get_fake_request() output = self.controller.index(request, UUID2) self.assertEqual(1, len(output['members'])) def test_index_forbidden_by_get_members_policy(self): rules = {"get_members": False} self.policy.set_rules(rules) request = unit_test_utils.get_fake_request() self.assertRaises(webob.exc.HTTPForbidden, self.controller.index, request, image_id=UUID2) def test_show(self): request = unit_test_utils.get_fake_request(tenant=TENANT1) output = self.controller.show(request, UUID2, TENANT4) expected = self.image_members[0] self.assertEqual(output.image_id, expected['image_id']) self.assertEqual(output.member_id, expected['member']) self.assertEqual(output.status, expected['status']) def test_show_by_member(self): request = unit_test_utils.get_fake_request(tenant=TENANT4) output = self.controller.show(request, UUID2, TENANT4) expected = self.image_members[0] self.assertEqual(output.image_id, expected['image_id']) self.assertEqual(output.member_id, expected['member']) self.assertEqual(output.status, expected['status']) def test_show_forbidden(self): request = unit_test_utils.get_fake_request(tenant=TENANT2) self.assertRaises(webob.exc.HTTPNotFound, self.controller.show, request, UUID2, TENANT4) def test_show_not_found(self): # one member should not be able to view status of another member # of the same image request = unit_test_utils.get_fake_request(tenant=TENANT2) self.assertRaises(webob.exc.HTTPNotFound, self.controller.show, request, UUID3, TENANT4) def test_create(self): request = unit_test_utils.get_fake_request() image_id = UUID2 member_id = TENANT3 output = self.controller.create(request, image_id=image_id, member_id=member_id) self.assertEqual(UUID2, output.image_id) self.assertEqual(TENANT3, output.member_id) def test_create_allowed_by_add_policy(self): rules = {"add_member": True} self.policy.set_rules(rules) request = unit_test_utils.get_fake_request() output = self.controller.create(request, image_id=UUID2, member_id=TENANT3) self.assertEqual(UUID2, output.image_id) self.assertEqual(TENANT3, output.member_id) def test_create_forbidden_by_add_policy(self): rules = {"add_member": False} self.policy.set_rules(rules) request = unit_test_utils.get_fake_request() self.assertRaises(webob.exc.HTTPForbidden, self.controller.create, request, image_id=UUID2, member_id=TENANT3) def test_create_duplicate_member(self): request = unit_test_utils.get_fake_request() image_id = UUID2 member_id = TENANT3 output = self.controller.create(request, image_id=image_id, member_id=member_id) self.assertEqual(UUID2, output.image_id) self.assertEqual(TENANT3, output.member_id) self.assertRaises(webob.exc.HTTPConflict, self.controller.create, request, image_id=image_id, member_id=member_id) def test_create_overlimit(self): self.config(image_member_quota=0) request = unit_test_utils.get_fake_request() image_id = UUID2 member_id = TENANT3 self.assertRaises(webob.exc.HTTPRequestEntityTooLarge, self.controller.create, request, image_id=image_id, member_id=member_id) def test_create_unlimited(self): self.config(image_member_quota=-1) request = unit_test_utils.get_fake_request() image_id = UUID2 member_id = TENANT3 output = self.controller.create(request, image_id=image_id, member_id=member_id) self.assertEqual(UUID2, output.image_id) self.assertEqual(TENANT3, output.member_id) def test_update_done_by_member(self): request = unit_test_utils.get_fake_request(tenant=TENANT4) image_id = UUID2 member_id = TENANT4 output = self.controller.update(request, image_id=image_id, member_id=member_id, status='accepted') self.assertEqual(UUID2, output.image_id) self.assertEqual(TENANT4, output.member_id) self.assertEqual('accepted', output.status) def test_update_done_by_member_forbidden_by_policy(self): rules = {"modify_member": False} self.policy.set_rules(rules) request = unit_test_utils.get_fake_request(tenant=TENANT4) self.assertRaises(webob.exc.HTTPForbidden, self.controller.update, request, image_id=UUID2, member_id=TENANT4, status='accepted') def test_update_done_by_member_allowed_by_policy(self): rules = {"modify_member": True} self.policy.set_rules(rules) request = unit_test_utils.get_fake_request(tenant=TENANT4) output = self.controller.update(request, image_id=UUID2, member_id=TENANT4, status='accepted') self.assertEqual(UUID2, output.image_id) self.assertEqual(TENANT4, output.member_id) self.assertEqual('accepted', output.status) def test_update_done_by_owner(self): request = unit_test_utils.get_fake_request(tenant=TENANT1) self.assertRaises(webob.exc.HTTPForbidden, self.controller.update, request, UUID2, TENANT4, status='accepted') def test_update_invalid_status(self): request = unit_test_utils.get_fake_request(tenant=TENANT4) self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update, request, UUID2, TENANT4, status='accept') def test_create_private_image(self): request = unit_test_utils.get_fake_request() self.assertRaises(webob.exc.HTTPForbidden, self.controller.create, request, UUID4, TENANT2) def test_create_public_image(self): request = unit_test_utils.get_fake_request() self.assertRaises(webob.exc.HTTPForbidden, self.controller.create, request, UUID1, TENANT2) def test_create_image_does_not_exist(self): request = unit_test_utils.get_fake_request() image_id = 'fake-image-id' member_id = TENANT3 self.assertRaises(webob.exc.HTTPNotFound, self.controller.create, request, image_id=image_id, member_id=member_id) def test_delete(self): request = unit_test_utils.get_fake_request() member_id = TENANT4 image_id = UUID2 res = self.controller.delete(request, image_id, member_id) self.assertEqual(res.body, '') self.assertEqual(res.status_code, 204) found_member = self.db.image_member_find( request.context, image_id=image_id, member=member_id) self.assertEqual(found_member, []) def test_delete_by_member(self): request = unit_test_utils.get_fake_request(tenant=TENANT4) self.assertRaises(webob.exc.HTTPForbidden, self.controller.delete, request, UUID2, TENANT4) request = unit_test_utils.get_fake_request() output = self.controller.index(request, UUID2) self.assertEqual(1, len(output['members'])) actual = set([image_member.member_id for image_member in output['members']]) expected = set([TENANT4]) self.assertEqual(actual, expected) def test_delete_allowed_by_policies(self): rules = {"get_member": True, "delete_member": True} self.policy.set_rules(rules) request = unit_test_utils.get_fake_request(tenant=TENANT1) output = self.controller.delete(request, image_id=UUID2, member_id=TENANT4) request = unit_test_utils.get_fake_request() output = self.controller.index(request, UUID2) self.assertEqual(0, len(output['members'])) def test_delete_forbidden_by_get_member_policy(self): rules = {"get_member": False} self.policy.set_rules(rules) request = unit_test_utils.get_fake_request(tenant=TENANT1) self.assertRaises(webob.exc.HTTPForbidden, self.controller.delete, request, UUID2, TENANT4) def test_delete_forbidden_by_delete_member_policy(self): rules = {"delete_member": False} self.policy.set_rules(rules) request = unit_test_utils.get_fake_request(tenant=TENANT1) self.assertRaises(webob.exc.HTTPForbidden, self.controller.delete, request, UUID2, TENANT4) def test_delete_private_image(self): request = unit_test_utils.get_fake_request() self.assertRaises(webob.exc.HTTPForbidden, self.controller.delete, request, UUID4, TENANT1) def test_delete_public_image(self): request = unit_test_utils.get_fake_request() self.assertRaises(webob.exc.HTTPForbidden, self.controller.delete, request, UUID1, TENANT1) def test_delete_image_does_not_exist(self): request = unit_test_utils.get_fake_request() member_id = TENANT2 image_id = 'fake-image-id' self.assertRaises(webob.exc.HTTPNotFound, self.controller.delete, request, image_id, member_id) def test_delete_member_does_not_exist(self): request = unit_test_utils.get_fake_request() member_id = 'fake-member-id' image_id = UUID2 found_member = self.db.image_member_find( request.context, image_id=image_id, member=member_id) self.assertEqual(found_member, []) self.assertRaises(webob.exc.HTTPNotFound, self.controller.delete, request, image_id, member_id) class TestImageMembersSerializer(test_utils.BaseTestCase): def setUp(self): super(TestImageMembersSerializer, self).setUp() self.serializer = glance.api.v2.image_members.ResponseSerializer() self.fixtures = [ _domain_fixture(id='1', image_id=UUID2, member_id=TENANT1, status='accepted', created_at=DATETIME, updated_at=DATETIME), _domain_fixture(id='2', image_id=UUID2, member_id=TENANT2, status='pending', created_at=DATETIME, updated_at=DATETIME), ] def test_index(self): expected = { 'members': [ { 'image_id': UUID2, 'member_id': TENANT1, 'status': 'accepted', 'created_at': ISOTIME, 'updated_at': ISOTIME, 'schema': '/v2/schemas/member', }, { 'image_id': UUID2, 'member_id': TENANT2, 'status': 'pending', 'created_at': ISOTIME, 'updated_at': ISOTIME, 'schema': '/v2/schemas/member', }, ], 'schema': '/v2/schemas/members', } request = webob.Request.blank('/v2/images/%s/members' % UUID2) response = webob.Response(request=request) result = {'members': self.fixtures} self.serializer.index(response, result) actual = jsonutils.loads(response.body) self.assertEqual(expected, actual) self.assertEqual('application/json', response.content_type) def test_show(self): expected = { 'image_id': UUID2, 'member_id': TENANT1, 'status': 'accepted', 'created_at': ISOTIME, 'updated_at': ISOTIME, 'schema': '/v2/schemas/member', } request = webob.Request.blank('/v2/images/%s/members/%s' % (UUID2, TENANT1)) response = webob.Response(request=request) result = self.fixtures[0] self.serializer.show(response, result) actual = jsonutils.loads(response.body) self.assertEqual(expected, actual) self.assertEqual('application/json', response.content_type) def test_create(self): expected = {'image_id': UUID2, 'member_id': TENANT1, 'status': 'accepted', 'schema': '/v2/schemas/member', 'created_at': ISOTIME, 'updated_at': ISOTIME} request = webob.Request.blank('/v2/images/%s/members/%s' % (UUID2, TENANT1)) response = webob.Response(request=request) result = self.fixtures[0] self.serializer.create(response, result) actual = jsonutils.loads(response.body) self.assertEqual(expected, actual) self.assertEqual('application/json', response.content_type) def test_update(self): expected = {'image_id': UUID2, 'member_id': TENANT1, 'status': 'accepted', 'schema': '/v2/schemas/member', 'created_at': ISOTIME, 'updated_at': ISOTIME} request = webob.Request.blank('/v2/images/%s/members/%s' % (UUID2, TENANT1)) response = webob.Response(request=request) result = self.fixtures[0] self.serializer.update(response, result) actual = jsonutils.loads(response.body) self.assertEqual(expected, actual) self.assertEqual('application/json', response.content_type) class TestImagesDeserializer(test_utils.BaseTestCase): def setUp(self): super(TestImagesDeserializer, self).setUp() self.deserializer = glance.api.v2.image_members.RequestDeserializer() def test_create(self): request = unit_test_utils.get_fake_request() request.body = jsonutils.dumps({'member': TENANT1}) output = self.deserializer.create(request) expected = {'member_id': TENANT1} self.assertEqual(expected, output) def test_create_invalid(self): request = unit_test_utils.get_fake_request() request.body = jsonutils.dumps({'mem': TENANT1}) self.assertRaises(webob.exc.HTTPBadRequest, self.deserializer.create, request) def test_create_no_body(self): request = unit_test_utils.get_fake_request() self.assertRaises(webob.exc.HTTPBadRequest, self.deserializer.create, request) def test_create_member_empty(self): request = unit_test_utils.get_fake_request() request.body = jsonutils.dumps({'member': ''}) self.assertRaises(webob.exc.HTTPBadRequest, self.deserializer.create, request) def test_update(self): request = unit_test_utils.get_fake_request() request.body = jsonutils.dumps({'status': 'accepted'}) output = self.deserializer.update(request) expected = {'status': 'accepted'} self.assertEqual(expected, output) def test_update_invalid(self): request = unit_test_utils.get_fake_request() request.body = jsonutils.dumps({'mem': TENANT1}) self.assertRaises(webob.exc.HTTPBadRequest, self.deserializer.update, request) def test_update_no_body(self): request = unit_test_utils.get_fake_request() self.assertRaises(webob.exc.HTTPBadRequest, self.deserializer.update, request) glance-2014.1/glance/tests/unit/v2/test_image_data_resource.py0000664000175400017540000004163312323736226025501 0ustar jenkinsjenkins00000000000000# Copyright 2012 OpenStack Foundation. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import mock import uuid import six import webob import glance.api.v2.image_data from glance.common import exception from glance.tests.unit import base import glance.tests.unit.utils as unit_test_utils import glance.tests.utils as test_utils class Raise(object): def __init__(self, exc): self.exc = exc def __call__(self, *args, **kwargs): raise self.exc class FakeImage(object): def __init__(self, image_id=None, data=None, checksum=None, size=0, virtual_size=0, locations=None, container_format='bear', disk_format='rawr', status=None): self.image_id = image_id self.data = data self.checksum = checksum self.size = size self.virtual_size = virtual_size self.locations = locations self.container_format = container_format self.disk_format = disk_format self._status = status @property def status(self): return self._status @status.setter def status(self, value): if isinstance(self._status, BaseException): raise self._status else: self._status = value def get_data(self): return self.data def set_data(self, data, size=None): self.data = ''.join(data) self.size = size self.status = 'modified-by-fake' class FakeImageRepo(object): def __init__(self, result=None): self.result = result def get(self, image_id): if isinstance(self.result, BaseException): raise self.result else: return self.result def save(self, image): self.saved_image = image class FakeGateway(object): def __init__(self, repo): self.repo = repo def get_repo(self, context): return self.repo class TestImagesController(base.StoreClearingUnitTest): def setUp(self): super(TestImagesController, self).setUp() self.config(verbose=True, debug=True) self.image_repo = FakeImageRepo() self.gateway = FakeGateway(self.image_repo) self.controller = glance.api.v2.image_data.ImageDataController( gateway=self.gateway) def test_download(self): request = unit_test_utils.get_fake_request() image = FakeImage('abcd', locations=['http://example.com/image']) self.image_repo.result = image image = self.controller.download(request, unit_test_utils.UUID1) self.assertEqual(image.image_id, 'abcd') def test_download_no_location(self): request = unit_test_utils.get_fake_request() self.image_repo.result = FakeImage('abcd') self.assertRaises(webob.exc.HTTPNoContent, self.controller.download, request, unit_test_utils.UUID2) def test_download_non_existent_image(self): request = unit_test_utils.get_fake_request() self.image_repo.result = exception.NotFound() self.assertRaises(webob.exc.HTTPNotFound, self.controller.download, request, str(uuid.uuid4())) def test_download_forbidden(self): request = unit_test_utils.get_fake_request() self.image_repo.result = exception.Forbidden() self.assertRaises(webob.exc.HTTPForbidden, self.controller.download, request, str(uuid.uuid4())) def test_download_get_image_location_forbidden(self): class ImageLocations(object): def __len__(self): raise exception.Forbidden() request = unit_test_utils.get_fake_request() image = FakeImage('abcd') self.image_repo.result = image image.locations = ImageLocations() self.assertRaises(webob.exc.HTTPForbidden, self.controller.download, request, str(uuid.uuid4())) def test_upload(self): request = unit_test_utils.get_fake_request() image = FakeImage('abcd') self.image_repo.result = image self.controller.upload(request, unit_test_utils.UUID2, 'YYYY', 4) self.assertEqual(image.data, 'YYYY') self.assertEqual(image.size, 4) def test_upload_status(self): request = unit_test_utils.get_fake_request() image = FakeImage('abcd') self.image_repo.result = image insurance = {'called': False} def read_data(): insurance['called'] = True self.assertEqual(self.image_repo.saved_image.status, 'saving') yield 'YYYY' self.controller.upload(request, unit_test_utils.UUID2, read_data(), None) self.assertTrue(insurance['called']) self.assertEqual(self.image_repo.saved_image.status, 'modified-by-fake') def test_upload_no_size(self): request = unit_test_utils.get_fake_request() image = FakeImage('abcd') self.image_repo.result = image self.controller.upload(request, unit_test_utils.UUID2, 'YYYY', None) self.assertEqual(image.data, 'YYYY') self.assertIsNone(image.size) def test_upload_invalid(self): request = unit_test_utils.get_fake_request() image = FakeImage('abcd') image.status = ValueError() self.image_repo.result = image self.assertRaises(webob.exc.HTTPBadRequest, self.controller.upload, request, unit_test_utils.UUID1, 'YYYY', 4) def test_upload_non_existent_image_during_save_initiates_deletion(self): def fake_save(self): raise exception.NotFound() request = unit_test_utils.get_fake_request() image = FakeImage('abcd', locations=['http://example.com/image']) self.image_repo.result = image self.image_repo.save = fake_save image.delete = mock.Mock() self.assertRaises(webob.exc.HTTPGone, self.controller.upload, request, str(uuid.uuid4()), 'ABC', 3) self.assertTrue(image.delete.called) def test_upload_non_existent_image_before_save(self): request = unit_test_utils.get_fake_request() self.image_repo.result = exception.NotFound() self.assertRaises(webob.exc.HTTPNotFound, self.controller.upload, request, str(uuid.uuid4()), 'ABC', 3) def test_upload_data_exists(self): request = unit_test_utils.get_fake_request() image = FakeImage() exc = exception.InvalidImageStatusTransition(cur_status='active', new_status='queued') image.set_data = Raise(exc) self.image_repo.result = image self.assertRaises(webob.exc.HTTPConflict, self.controller.upload, request, unit_test_utils.UUID1, 'YYYY', 4) def test_upload_storage_full(self): request = unit_test_utils.get_fake_request() image = FakeImage() image.set_data = Raise(exception.StorageFull) self.image_repo.result = image self.assertRaises(webob.exc.HTTPRequestEntityTooLarge, self.controller.upload, request, unit_test_utils.UUID2, 'YYYYYYY', 7) def test_image_size_limit_exceeded(self): request = unit_test_utils.get_fake_request() image = FakeImage() image.set_data = Raise(exception.ImageSizeLimitExceeded) self.image_repo.result = image self.assertRaises(webob.exc.HTTPRequestEntityTooLarge, self.controller.upload, request, unit_test_utils.UUID1, 'YYYYYYY', 7) def test_upload_storage_forbidden(self): request = unit_test_utils.get_fake_request(user=unit_test_utils.USER2) image = FakeImage() image.set_data = Raise(exception.Forbidden) self.image_repo.result = image self.assertRaises(webob.exc.HTTPForbidden, self.controller.upload, request, unit_test_utils.UUID2, 'YY', 2) def test_upload_storage_write_denied(self): request = unit_test_utils.get_fake_request(user=unit_test_utils.USER3) image = FakeImage() image.set_data = Raise(exception.StorageWriteDenied) self.image_repo.result = image self.assertRaises(webob.exc.HTTPServiceUnavailable, self.controller.upload, request, unit_test_utils.UUID2, 'YY', 2) def _test_upload_download_prepare_notification(self): request = unit_test_utils.get_fake_request() self.controller.upload(request, unit_test_utils.UUID2, 'YYYY', 4) output = self.controller.download(request, unit_test_utils.UUID2) output_log = self.notifier.get_logs() prepare_payload = output['meta'].copy() prepare_payload['checksum'] = None prepare_payload['size'] = None prepare_payload['virtual_size'] = None prepare_payload['location'] = None prepare_payload['status'] = 'queued' del prepare_payload['updated_at'] prepare_log = { 'notification_type': "INFO", 'event_type': "image.prepare", 'payload': prepare_payload, } self.assertEqual(len(output_log), 3) prepare_updated_at = output_log[0]['payload']['updated_at'] del output_log[0]['payload']['updated_at'] self.assertTrue(prepare_updated_at <= output['meta']['updated_at']) self.assertEqual(output_log[0], prepare_log) def _test_upload_download_upload_notification(self): request = unit_test_utils.get_fake_request() self.controller.upload(request, unit_test_utils.UUID2, 'YYYY', 4) output = self.controller.download(request, unit_test_utils.UUID2) output_log = self.notifier.get_logs() upload_payload = output['meta'].copy() upload_log = { 'notification_type': "INFO", 'event_type': "image.upload", 'payload': upload_payload, } self.assertEqual(len(output_log), 3) self.assertEqual(output_log[1], upload_log) def _test_upload_download_activate_notification(self): request = unit_test_utils.get_fake_request() self.controller.upload(request, unit_test_utils.UUID2, 'YYYY', 4) output = self.controller.download(request, unit_test_utils.UUID2) output_log = self.notifier.get_logs() activate_payload = output['meta'].copy() activate_log = { 'notification_type': "INFO", 'event_type': "image.activate", 'payload': activate_payload, } self.assertEqual(len(output_log), 3) self.assertEqual(output_log[2], activate_log) def test_restore_image_when_upload_failed(self): request = unit_test_utils.get_fake_request() image = FakeImage('fake') image.set_data = Raise(exception.StorageWriteDenied) self.image_repo.result = image self.assertRaises(webob.exc.HTTPServiceUnavailable, self.controller.upload, request, unit_test_utils.UUID2, 'ZZZ', 3) self.assertEqual(self.image_repo.saved_image.status, 'queued') class TestImageDataDeserializer(test_utils.BaseTestCase): def setUp(self): super(TestImageDataDeserializer, self).setUp() self.deserializer = glance.api.v2.image_data.RequestDeserializer() def test_upload(self): request = unit_test_utils.get_fake_request() request.headers['Content-Type'] = 'application/octet-stream' request.body = 'YYY' request.headers['Content-Length'] = 3 output = self.deserializer.upload(request) data = output.pop('data') self.assertEqual(data.read(), 'YYY') expected = {'size': 3} self.assertEqual(expected, output) def test_upload_chunked(self): request = unit_test_utils.get_fake_request() request.headers['Content-Type'] = 'application/octet-stream' # If we use body_file, webob assumes we want to do a chunked upload, # ignoring the Content-Length header request.body_file = six.StringIO('YYY') output = self.deserializer.upload(request) data = output.pop('data') self.assertEqual(data.read(), 'YYY') expected = {'size': None} self.assertEqual(expected, output) def test_upload_chunked_with_content_length(self): request = unit_test_utils.get_fake_request() request.headers['Content-Type'] = 'application/octet-stream' request.body_file = six.StringIO('YYY') # The deserializer shouldn't care if the Content-Length is # set when the user is attempting to send chunked data. request.headers['Content-Length'] = 3 output = self.deserializer.upload(request) data = output.pop('data') self.assertEqual(data.read(), 'YYY') expected = {'size': 3} self.assertEqual(expected, output) def test_upload_with_incorrect_content_length(self): request = unit_test_utils.get_fake_request() request.headers['Content-Type'] = 'application/octet-stream' # The deserializer shouldn't care if the Content-Length and # actual request body length differ. That job is left up # to the controller request.body = 'YYY' request.headers['Content-Length'] = 4 output = self.deserializer.upload(request) data = output.pop('data') self.assertEqual(data.read(), 'YYY') expected = {'size': 4} self.assertEqual(expected, output) def test_upload_wrong_content_type(self): request = unit_test_utils.get_fake_request() request.headers['Content-Type'] = 'application/json' request.body = 'YYYYY' self.assertRaises(webob.exc.HTTPUnsupportedMediaType, self.deserializer.upload, request) request = unit_test_utils.get_fake_request() request.headers['Content-Type'] = 'application/octet-st' request.body = 'YYYYY' self.assertRaises(webob.exc.HTTPUnsupportedMediaType, self.deserializer.upload, request) class TestImageDataSerializer(test_utils.BaseTestCase): def setUp(self): super(TestImageDataSerializer, self).setUp() self.serializer = glance.api.v2.image_data.ResponseSerializer() def test_download(self): request = webob.Request.blank('/') request.environ = {} response = webob.Response() response.request = request image = FakeImage(size=3, data=iter('ZZZ')) self.serializer.download(response, image) self.assertEqual('ZZZ', response.body) self.assertEqual('3', response.headers['Content-Length']) self.assertFalse('Content-MD5' in response.headers) self.assertEqual('application/octet-stream', response.headers['Content-Type']) def test_download_with_checksum(self): request = webob.Request.blank('/') request.environ = {} response = webob.Response() response.request = request checksum = '0745064918b49693cca64d6b6a13d28a' image = FakeImage(size=3, checksum=checksum, data=iter('ZZZ')) self.serializer.download(response, image) self.assertEqual('ZZZ', response.body) self.assertEqual('3', response.headers['Content-Length']) self.assertEqual(checksum, response.headers['Content-MD5']) self.assertEqual('application/octet-stream', response.headers['Content-Type']) def test_download_forbidden(self): """Make sure the serializer can return 403 forbidden error instead of 500 internal server error. """ def get_data(): raise exception.Forbidden() self.stubs.Set(glance.api.policy.ImageProxy, 'get_data', get_data) request = webob.Request.blank('/') request.environ = {} response = webob.Response() response.request = request image = FakeImage(size=3, data=iter('ZZZ')) image.get_data = get_data self.assertRaises(webob.exc.HTTPForbidden, self.serializer.download, response, image) def test_upload(self): request = webob.Request.blank('/') request.environ = {} response = webob.Response() response.request = request self.serializer.upload(response, {}) self.assertEqual(204, response.status_int) self.assertEqual('0', response.headers['Content-Length']) glance-2014.1/glance/tests/unit/v2/test_tasks_resource.py0000664000175400017540000007055312323736230024551 0ustar jenkinsjenkins00000000000000# Copyright 2013 IBM Corp. # 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 datetime import uuid import webob import glance.api.v2.tasks import glance.domain from glance.openstack.common import jsonutils from glance.openstack.common import timeutils from glance.tests.unit import base import glance.tests.unit.utils as unit_test_utils import glance.tests.utils as test_utils UUID1 = 'c80a1a6c-bd1f-41c5-90ee-81afedb1d58d' UUID2 = 'a85abd86-55b3-4d5b-b0b4-5d0a6e6042fc' UUID3 = '971ec09a-8067-4bc8-a91f-ae3557f1c4c7' UUID4 = '6bbe7cc2-eae7-4c0f-b50d-a7160b0c6a86' TENANT1 = '6838eb7b-6ded-434a-882c-b344c77fe8df' TENANT2 = '2c014f32-55eb-467d-8fcb-4bd706012f81' TENANT3 = '5a3e60e8-cfa9-4a9e-a90a-62b42cea92b8' TENANT4 = 'c6c87f25-8a94-47ed-8c83-053c25f42df4' DATETIME = datetime.datetime(2013, 9, 28, 15, 27, 36, 325355) ISOTIME = '2013-09-28T15:27:36Z' def _db_fixture(task_id, **kwargs): default_datetime = timeutils.utcnow() obj = { 'id': task_id, 'status': 'pending', 'type': 'import', 'input': {}, 'result': None, 'owner': None, 'message': None, 'expires_at': None, 'created_at': default_datetime, 'updated_at': default_datetime, 'deleted_at': None, 'deleted': False } obj.update(kwargs) return obj def _domain_fixture(task_id, **kwargs): default_datetime = timeutils.utcnow() task_properties = { 'task_id': task_id, 'status': kwargs.get('status', 'pending'), 'task_type': kwargs.get('type', 'import'), 'owner': kwargs.get('owner', None), 'expires_at': kwargs.get('expires_at', None), 'created_at': kwargs.get('created_at', default_datetime), 'updated_at': kwargs.get('updated_at', default_datetime), } task = glance.domain.Task(**task_properties) task_details = glance.domain.TaskDetails(task_id, kwargs.get('input', {}), kwargs.get('message', None), kwargs.get('result', None)) return {'task': task, 'task_details': task_details} class TestTasksController(test_utils.BaseTestCase): def setUp(self): super(TestTasksController, self).setUp() self.db = unit_test_utils.FakeDB() self.policy = unit_test_utils.FakePolicyEnforcer() self.notifier = unit_test_utils.FakeNotifier() self.store = unit_test_utils.FakeStoreAPI() self._create_tasks() self.controller = glance.api.v2.tasks.TasksController(self.db, self.policy, self.notifier, self.store) def _create_tasks(self): self.db.reset() now = timeutils.utcnow() times = [now + datetime.timedelta(seconds=5 * i) for i in range(4)] self.tasks = [ _db_fixture(UUID1, owner=TENANT1, created_at=times[0], updated_at=times[0]), # FIXME(venkatesh): change the type to include clone and export # once they are included as a valid types under Task domain model. _db_fixture(UUID2, owner=TENANT2, type='import', created_at=times[1], updated_at=times[1]), _db_fixture(UUID3, owner=TENANT3, type='import', created_at=times[2], updated_at=times[2]), _db_fixture(UUID4, owner=TENANT4, type='import', created_at=times[3], updated_at=times[3])] [self.db.task_create(None, task) for task in self.tasks] def test_index(self): self.config(limit_param_default=1, api_limit_max=3) request = unit_test_utils.get_fake_request() output = self.controller.index(request) self.assertEqual(1, len(output['tasks'])) actual = set([task.task_id for task in output['tasks']]) expected = set([UUID1]) self.assertEqual(actual, expected) def test_index_admin(self): request = unit_test_utils.get_fake_request(is_admin=True) output = self.controller.index(request) self.assertEqual(4, len(output['tasks'])) def test_index_return_parameters(self): self.config(limit_param_default=1, api_limit_max=4) request = unit_test_utils.get_fake_request(is_admin=True) output = self.controller.index(request, marker=UUID3, limit=1, sort_key='created_at', sort_dir='desc') self.assertEqual(1, len(output['tasks'])) actual = set([task.task_id for task in output['tasks']]) expected = set([UUID2]) self.assertEqual(expected, actual) self.assertEqual(UUID2, output['next_marker']) def test_index_next_marker(self): self.config(limit_param_default=1, api_limit_max=3) request = unit_test_utils.get_fake_request(is_admin=True) output = self.controller.index(request, marker=UUID3, limit=2) self.assertEqual(2, len(output['tasks'])) actual = set([task.task_id for task in output['tasks']]) expected = set([UUID2, UUID1]) self.assertEqual(actual, expected) self.assertEqual(UUID1, output['next_marker']) def test_index_no_next_marker(self): self.config(limit_param_default=1, api_limit_max=3) request = unit_test_utils.get_fake_request(is_admin=True) output = self.controller.index(request, marker=UUID1, limit=2) self.assertEqual(0, len(output['tasks'])) actual = set([task.task_id for task in output['tasks']]) expected = set([]) self.assertEqual(actual, expected) self.assertTrue('next_marker' not in output) def test_index_with_id_filter(self): request = unit_test_utils.get_fake_request('/tasks?id=%s' % UUID1) output = self.controller.index(request, filters={'id': UUID1}) self.assertEqual(1, len(output['tasks'])) actual = set([task.task_id for task in output['tasks']]) expected = set([UUID1]) self.assertEqual(actual, expected) def test_index_with_filters_return_many(self): path = '/tasks?status=pending' request = unit_test_utils.get_fake_request(path, is_admin=True) output = self.controller.index(request, filters={'status': 'pending'}) self.assertEqual(4, len(output['tasks'])) actual = set([task.task_id for task in output['tasks']]) expected = set([UUID1, UUID2, UUID3, UUID4]) self.assertEqual(sorted(actual), sorted(expected)) def test_index_with_many_filters(self): url = '/tasks?status=pending&type=import' request = unit_test_utils.get_fake_request(url, is_admin=True) output = self.controller.index(request, filters={ 'status': 'pending', 'type': 'import', 'owner': TENANT1, }) self.assertEqual(1, len(output['tasks'])) actual = set([task.task_id for task in output['tasks']]) expected = set([UUID1]) self.assertEqual(actual, expected) def test_index_with_marker(self): self.config(limit_param_default=1, api_limit_max=3) path = '/tasks' request = unit_test_utils.get_fake_request(path, is_admin=True) output = self.controller.index(request, marker=UUID3) actual = set([task.task_id for task in output['tasks']]) self.assertEqual(1, len(actual)) self.assertTrue(UUID2 in actual) def test_index_with_limit(self): path = '/tasks' limit = 2 request = unit_test_utils.get_fake_request(path, is_admin=True) output = self.controller.index(request, limit=limit) actual = set([task.task_id for task in output['tasks']]) self.assertEqual(limit, len(actual)) def test_index_greater_than_limit_max(self): self.config(limit_param_default=1, api_limit_max=3) path = '/tasks' request = unit_test_utils.get_fake_request(path, is_admin=True) output = self.controller.index(request, limit=4) actual = set([task.task_id for task in output['tasks']]) self.assertEqual(3, len(actual)) self.assertTrue(output['next_marker'] not in output) def test_index_default_limit(self): self.config(limit_param_default=1, api_limit_max=3) path = '/tasks' request = unit_test_utils.get_fake_request(path) output = self.controller.index(request) actual = set([task.task_id for task in output['tasks']]) self.assertEqual(1, len(actual)) def test_index_with_sort_dir(self): path = '/tasks' request = unit_test_utils.get_fake_request(path, is_admin=True) output = self.controller.index(request, sort_dir='asc', limit=3) actual = [task.task_id for task in output['tasks']] self.assertEqual(3, len(actual)) self.assertEqual(actual, [UUID1, UUID2, UUID3]) def test_index_with_sort_key(self): path = '/tasks' request = unit_test_utils.get_fake_request(path, is_admin=True) output = self.controller.index(request, sort_key='created_at', limit=3) actual = [task.task_id for task in output['tasks']] self.assertEqual(3, len(actual)) self.assertEqual(UUID4, actual[0]) self.assertEqual(UUID3, actual[1]) self.assertEqual(UUID2, actual[2]) def test_index_with_marker_not_found(self): fake_uuid = str(uuid.uuid4()) path = '/tasks' request = unit_test_utils.get_fake_request(path) self.assertRaises(webob.exc.HTTPBadRequest, self.controller.index, request, marker=fake_uuid) def test_index_with_marker_is_not_like_uuid(self): marker = 'INVALID_UUID' path = '/tasks' request = unit_test_utils.get_fake_request(path) self.assertRaises(webob.exc.HTTPBadRequest, self.controller.index, request, marker=marker) def test_index_invalid_sort_key(self): path = '/tasks' request = unit_test_utils.get_fake_request(path) self.assertRaises(webob.exc.HTTPBadRequest, self.controller.index, request, sort_key='foo') def test_index_zero_tasks(self): self.db.reset() request = unit_test_utils.get_fake_request() output = self.controller.index(request) self.assertEqual([], output['tasks']) def test_get(self): request = unit_test_utils.get_fake_request() output = self.controller.get(request, task_id=UUID1) task = output['task'] task_details = output['task_details'] self.assertEqual(UUID1, task.task_id) self.assertEqual(UUID1, task_details.task_id) self.assertEqual('import', task.type) def test_get_non_existent(self): request = unit_test_utils.get_fake_request() task_id = str(uuid.uuid4()) self.assertRaises(webob.exc.HTTPNotFound, self.controller.get, request, task_id) def test_get_not_allowed(self): request = unit_test_utils.get_fake_request() self.assertEqual(request.context.tenant, TENANT1) self.assertRaises(webob.exc.HTTPNotFound, self.controller.get, request, UUID4) def test_create(self): request = unit_test_utils.get_fake_request() task = {"type": "import", "input": { "import_from": "swift://cloud.foo/myaccount/mycontainer/path", "image_from_format": "qcow2"} } output = self.controller.create(request, task=task) task = output['task'] task_details = output['task_details'] self.assertEqual('import', task.type) self.assertEqual({ "import_from": "swift://cloud.foo/myaccount/mycontainer/path", "image_from_format": "qcow2"}, task_details.input) output_logs = [nlog for nlog in self.notifier.get_logs() if nlog['event_type'] == 'task.create'] self.assertEqual(len(output_logs), 1) output_log = output_logs[0] self.assertEqual(output_log['notification_type'], 'INFO') self.assertEqual(output_log['event_type'], 'task.create') class TestTasksControllerPolicies(base.IsolatedUnitTest): def setUp(self): super(TestTasksControllerPolicies, self).setUp() self.db = unit_test_utils.FakeDB() self.policy = unit_test_utils.FakePolicyEnforcer() self.controller = glance.api.v2.tasks.TasksController(self.db, self.policy) def test_index_unauthorized(self): rules = {"get_tasks": False} self.policy.set_rules(rules) request = unit_test_utils.get_fake_request() self.assertRaises(webob.exc.HTTPForbidden, self.controller.index, request) def test_get_unauthorized(self): rules = {"get_task": False} self.policy.set_rules(rules) request = unit_test_utils.get_fake_request() self.assertRaises(webob.exc.HTTPForbidden, self.controller.get, request, task_id=UUID2) def test_create_task_unauthorized(self): rules = {"add_task": False} self.policy.set_rules(rules) request = unit_test_utils.get_fake_request() task = {'type': 'import', 'input': {"import_from": "fake"}} self.assertRaises(webob.exc.HTTPForbidden, self.controller.create, request, task) def test_delete(self): request = unit_test_utils.get_fake_request() self.assertRaises(webob.exc.HTTPMethodNotAllowed, self.controller.delete, request, 'fake_id') class TestTasksDeserializer(test_utils.BaseTestCase): def setUp(self): super(TestTasksDeserializer, self).setUp() self.deserializer = glance.api.v2.tasks.RequestDeserializer() def test_create_no_body(self): request = unit_test_utils.get_fake_request() self.assertRaises(webob.exc.HTTPBadRequest, self.deserializer.create, request) def test_create(self): request = unit_test_utils.get_fake_request() request.body = jsonutils.dumps({ 'type': 'import', 'input': {'import_from': 'swift://cloud.foo/myaccount/mycontainer/path', 'import_from_format': 'qcow2', 'image_properties': {'name': 'fake1'}}, }) output = self.deserializer.create(request) properties = { 'type': 'import', 'input': {'import_from': 'swift://cloud.foo/myaccount/mycontainer/path', 'import_from_format': 'qcow2', 'image_properties': {'name': 'fake1'}}, } self.maxDiff = None expected = {'task': properties} self.assertEqual(expected, output) def test_index(self): marker = str(uuid.uuid4()) path = '/tasks?limit=1&marker=%s' % marker request = unit_test_utils.get_fake_request(path) expected = {'limit': 1, 'marker': marker, 'sort_key': 'created_at', 'sort_dir': 'desc', 'filters': {}} output = self.deserializer.index(request) self.assertEqual(output, expected) def test_index_strip_params_from_filters(self): type = 'import' path = '/tasks?type=%s' % type request = unit_test_utils.get_fake_request(path) output = self.deserializer.index(request) self.assertEqual(output['filters']['type'], type) def test_index_with_many_filter(self): status = 'success' type = 'import' path = '/tasks?status=%(status)s&type=%(type)s' % {'status': status, 'type': type} request = unit_test_utils.get_fake_request(path) output = self.deserializer.index(request) self.assertEqual(output['filters']['status'], status) self.assertEqual(output['filters']['type'], type) def test_index_with_filter_and_limit(self): status = 'success' path = '/tasks?status=%s&limit=1' % status request = unit_test_utils.get_fake_request(path) output = self.deserializer.index(request) self.assertEqual(output['filters']['status'], status) self.assertEqual(output['limit'], 1) def test_index_non_integer_limit(self): request = unit_test_utils.get_fake_request('/tasks?limit=blah') self.assertRaises(webob.exc.HTTPBadRequest, self.deserializer.index, request) def test_index_zero_limit(self): request = unit_test_utils.get_fake_request('/tasks?limit=0') expected = {'limit': 0, 'sort_key': 'created_at', 'sort_dir': 'desc', 'filters': {}} output = self.deserializer.index(request) self.assertEqual(expected, output) def test_index_negative_limit(self): path = '/tasks?limit=-1' request = unit_test_utils.get_fake_request(path) self.assertRaises(webob.exc.HTTPBadRequest, self.deserializer.index, request) def test_index_fraction(self): request = unit_test_utils.get_fake_request('/tasks?limit=1.1') self.assertRaises(webob.exc.HTTPBadRequest, self.deserializer.index, request) def test_index_invalid_status(self): path = '/tasks?status=blah' request = unit_test_utils.get_fake_request(path) self.assertRaises(webob.exc.HTTPBadRequest, self.deserializer.index, request) def test_index_marker(self): marker = str(uuid.uuid4()) path = '/tasks?marker=%s' % marker request = unit_test_utils.get_fake_request(path) output = self.deserializer.index(request) self.assertEqual(output.get('marker'), marker) def test_index_marker_not_specified(self): request = unit_test_utils.get_fake_request('/tasks') output = self.deserializer.index(request) self.assertFalse('marker' in output) def test_index_limit_not_specified(self): request = unit_test_utils.get_fake_request('/tasks') output = self.deserializer.index(request) self.assertFalse('limit' in output) def test_index_sort_key_id(self): request = unit_test_utils.get_fake_request('/tasks?sort_key=id') output = self.deserializer.index(request) expected = { 'sort_key': 'id', 'sort_dir': 'desc', 'filters': {} } self.assertEqual(output, expected) def test_index_sort_dir_asc(self): request = unit_test_utils.get_fake_request('/tasks?sort_dir=asc') output = self.deserializer.index(request) expected = { 'sort_key': 'created_at', 'sort_dir': 'asc', 'filters': {}} self.assertEqual(output, expected) def test_index_sort_dir_bad_value(self): request = unit_test_utils.get_fake_request('/tasks?sort_dir=invalid') self.assertRaises(webob.exc.HTTPBadRequest, self.deserializer.index, request) class TestTasksSerializer(test_utils.BaseTestCase): def setUp(self): super(TestTasksSerializer, self).setUp() self.serializer = glance.api.v2.tasks.ResponseSerializer() self.fixtures = [ _domain_fixture(UUID1, type='import', status='pending', input={'loc': 'fake'}, result={}, owner=TENANT1, message='', created_at=DATETIME, updated_at=DATETIME), _domain_fixture(UUID2, type='import', status='processing', input={'loc': 'bake'}, owner=TENANT2, message='', created_at=DATETIME, updated_at=DATETIME, result={}), _domain_fixture(UUID3, type='import', status='success', input={'loc': 'foo'}, owner=TENANT3, message='', created_at=DATETIME, updated_at=DATETIME, result={}, expires_at=DATETIME), _domain_fixture(UUID4, type='import', status='failure', input={'loc': 'boo'}, owner=TENANT4, message='', created_at=DATETIME, updated_at=DATETIME, result={}, expires_at=DATETIME), ] def test_index(self): expected = { 'tasks': [ { 'id': UUID1, 'type': 'import', 'status': 'pending', 'owner': TENANT1, 'created_at': ISOTIME, 'updated_at': ISOTIME, 'self': '/v2/tasks/%s' % UUID1, 'schema': '/v2/schemas/task', }, { 'id': UUID2, 'type': 'import', 'status': 'processing', 'owner': TENANT2, 'created_at': ISOTIME, 'updated_at': ISOTIME, 'self': '/v2/tasks/%s' % UUID2, 'schema': '/v2/schemas/task', }, { 'id': UUID3, 'type': 'import', 'status': 'success', 'owner': TENANT3, 'expires_at': ISOTIME, 'created_at': ISOTIME, 'updated_at': ISOTIME, 'self': '/v2/tasks/%s' % UUID3, 'schema': '/v2/schemas/task', }, { 'id': UUID4, 'type': 'import', 'status': 'failure', 'owner': TENANT4, 'expires_at': ISOTIME, 'created_at': ISOTIME, 'updated_at': ISOTIME, 'self': '/v2/tasks/%s' % UUID4, 'schema': '/v2/schemas/task', }, ], 'first': '/v2/tasks', 'schema': '/v2/schemas/tasks', } request = webob.Request.blank('/v2/tasks') response = webob.Response(request=request) task_fixtures = [f['task'] for f in self.fixtures] result = {'tasks': task_fixtures} self.serializer.index(response, result) actual = jsonutils.loads(response.body) self.assertEqual(expected, actual) self.assertEqual('application/json', response.content_type) def test_index_next_marker(self): request = webob.Request.blank('/v2/tasks') response = webob.Response(request=request) task_fixtures = [f['task'] for f in self.fixtures] result = {'tasks': task_fixtures, 'next_marker': UUID2} self.serializer.index(response, result) output = jsonutils.loads(response.body) self.assertEqual('/v2/tasks?marker=%s' % UUID2, output['next']) def test_index_carries_query_parameters(self): url = '/v2/tasks?limit=10&sort_key=id&sort_dir=asc' request = webob.Request.blank(url) response = webob.Response(request=request) task_fixtures = [f['task'] for f in self.fixtures] result = {'tasks': task_fixtures, 'next_marker': UUID2} self.serializer.index(response, result) output = jsonutils.loads(response.body) self.assertEqual('/v2/tasks?sort_key=id&sort_dir=asc&limit=10', output['first']) expect_next = '/v2/tasks?sort_key=id&sort_dir=asc&limit=10&marker=%s' self.assertEqual(expect_next % UUID2, output['next']) def test_get(self): expected = { 'id': UUID4, 'type': 'import', 'status': 'failure', 'input': {'loc': 'boo'}, 'result': {}, 'owner': TENANT4, 'message': '', 'created_at': ISOTIME, 'updated_at': ISOTIME, 'expires_at': ISOTIME, 'self': '/v2/tasks/%s' % UUID4, 'schema': '/v2/schemas/task', } response = webob.Response() self.serializer.get(response, self.fixtures[3]) actual = jsonutils.loads(response.body) self.assertEqual(expected, actual) self.assertEqual('application/json', response.content_type) def test_get_ensure_expires_at_not_returned(self): expected = { 'id': UUID1, 'type': 'import', 'status': 'pending', 'input': {'loc': 'fake'}, 'result': {}, 'owner': TENANT1, 'message': '', 'created_at': ISOTIME, 'updated_at': ISOTIME, 'self': '/v2/tasks/%s' % UUID1, 'schema': '/v2/schemas/task', } response = webob.Response() self.serializer.get(response, self.fixtures[0]) actual = jsonutils.loads(response.body) self.assertEqual(expected, actual) self.assertEqual('application/json', response.content_type) expected = { 'id': UUID2, 'type': 'import', 'status': 'processing', 'input': {'loc': 'bake'}, 'result': {}, 'owner': TENANT2, 'message': '', 'created_at': ISOTIME, 'updated_at': ISOTIME, 'self': '/v2/tasks/%s' % UUID2, 'schema': '/v2/schemas/task', } response = webob.Response() self.serializer.get(response, self.fixtures[1]) actual = jsonutils.loads(response.body) self.assertEqual(expected, actual) self.assertEqual('application/json', response.content_type) def test_create(self): response = webob.Response() self.serializer.create(response, self.fixtures[3]) serialized_task = jsonutils.loads(response.body) self.assertEqual(response.status_int, 201) self.assertEqual(self.fixtures[3]['task'].task_id, serialized_task['id']) self.assertEqual(self.fixtures[3]['task_details'].task_id, serialized_task['id']) self.assertEqual(self.fixtures[3]['task_details'].input, serialized_task['input']) self.assertTrue('expires_at' in serialized_task) self.assertEqual('application/json', response.content_type) def test_create_ensure_expires_at_is_not_returned(self): response = webob.Response() self.serializer.create(response, self.fixtures[0]) serialized_task = jsonutils.loads(response.body) self.assertEqual(response.status_int, 201) self.assertEqual(self.fixtures[0]['task'].task_id, serialized_task['id']) self.assertEqual(self.fixtures[0]['task_details'].task_id, serialized_task['id']) self.assertEqual(self.fixtures[0]['task_details'].input, serialized_task['input']) self.assertFalse('expires_at' in serialized_task) self.assertEqual('application/json', response.content_type) response = webob.Response() self.serializer.create(response, self.fixtures[1]) serialized_task = jsonutils.loads(response.body) self.assertEqual(response.status_int, 201) self.assertEqual(self.fixtures[1]['task'].task_id, serialized_task['id']) self.assertEqual(self.fixtures[1]['task_details'].task_id, serialized_task['id']) self.assertEqual(self.fixtures[1]['task_details'].input, serialized_task['input']) self.assertFalse('expires_at' in serialized_task) self.assertEqual('application/json', response.content_type) glance-2014.1/glance/tests/unit/v2/__init__.py0000664000175400017540000000000012323736226022176 0ustar jenkinsjenkins00000000000000glance-2014.1/glance/tests/unit/test_domain.py0000664000175400017540000004373712323736230022441 0ustar jenkinsjenkins00000000000000# Copyright 2012 OpenStack Foundation. # Copyright 2013 IBM Corp. # 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 datetime import uuid import mock from oslo.config import cfg from glance.common import exception from glance import domain from glance.openstack.common import timeutils import glance.tests.unit.utils as unittest_utils import glance.tests.utils as test_utils CONF = cfg.CONF UUID1 = 'c80a1a6c-bd1f-41c5-90ee-81afedb1d58d' TENANT1 = '6838eb7b-6ded-434a-882c-b344c77fe8df' class TestImageFactory(test_utils.BaseTestCase): def setUp(self): super(TestImageFactory, self).setUp() self.image_factory = domain.ImageFactory() def test_minimal_new_image(self): image = self.image_factory.new_image() self.assertTrue(image.image_id is not None) self.assertTrue(image.created_at is not None) self.assertEqual(image.created_at, image.updated_at) self.assertEqual(image.status, 'queued') self.assertEqual(image.visibility, 'private') self.assertIsNone(image.owner) self.assertIsNone(image.name) self.assertIsNone(image.size) self.assertEqual(image.min_disk, 0) self.assertEqual(image.min_ram, 0) self.assertEqual(image.protected, False) self.assertIsNone(image.disk_format) self.assertIsNone(image.container_format) self.assertEqual(image.extra_properties, {}) self.assertEqual(image.tags, set([])) def test_new_image(self): image = self.image_factory.new_image( image_id=UUID1, name='image-1', min_disk=256, owner=TENANT1) self.assertEqual(image.image_id, UUID1) self.assertTrue(image.created_at is not None) self.assertEqual(image.created_at, image.updated_at) self.assertEqual(image.status, 'queued') self.assertEqual(image.visibility, 'private') self.assertEqual(image.owner, TENANT1) self.assertEqual(image.name, 'image-1') self.assertIsNone(image.size) self.assertEqual(image.min_disk, 256) self.assertEqual(image.min_ram, 0) self.assertEqual(image.protected, False) self.assertIsNone(image.disk_format) self.assertIsNone(image.container_format) self.assertEqual(image.extra_properties, {}) self.assertEqual(image.tags, set([])) def test_new_image_with_extra_properties_and_tags(self): extra_properties = {'foo': 'bar'} tags = ['one', 'two'] image = self.image_factory.new_image( image_id=UUID1, name='image-1', extra_properties=extra_properties, tags=tags) self.assertEqual(image.image_id, UUID1) self.assertTrue(image.created_at is not None) self.assertEqual(image.created_at, image.updated_at) self.assertEqual(image.status, 'queued') self.assertEqual(image.visibility, 'private') self.assertIsNone(image.owner) self.assertEqual(image.name, 'image-1') self.assertIsNone(image.size) self.assertEqual(image.min_disk, 0) self.assertEqual(image.min_ram, 0) self.assertEqual(image.protected, False) self.assertIsNone(image.disk_format) self.assertIsNone(image.container_format) self.assertEqual(image.extra_properties, {'foo': 'bar'}) self.assertEqual(image.tags, set(['one', 'two'])) def test_new_image_read_only_property(self): self.assertRaises(exception.ReadonlyProperty, self.image_factory.new_image, image_id=UUID1, name='image-1', size=256) def test_new_image_unexpected_property(self): self.assertRaises(TypeError, self.image_factory.new_image, image_id=UUID1, image_name='name-1') def test_new_image_reserved_property(self): extra_properties = {'deleted': True} self.assertRaises(exception.ReservedProperty, self.image_factory.new_image, image_id=UUID1, extra_properties=extra_properties) class TestImage(test_utils.BaseTestCase): def setUp(self): super(TestImage, self).setUp() self.image_factory = domain.ImageFactory() self.image = self.image_factory.new_image( container_format='bear', disk_format='rawr') def test_extra_properties(self): self.image.extra_properties = {'foo': 'bar'} self.assertEqual(self.image.extra_properties, {'foo': 'bar'}) def test_extra_properties_assign(self): self.image.extra_properties['foo'] = 'bar' self.assertEqual(self.image.extra_properties, {'foo': 'bar'}) def test_delete_extra_properties(self): self.image.extra_properties = {'foo': 'bar'} self.assertEqual(self.image.extra_properties, {'foo': 'bar'}) del self.image.extra_properties['foo'] self.assertEqual(self.image.extra_properties, {}) def test_visibility_enumerated(self): self.image.visibility = 'public' self.image.visibility = 'private' self.assertRaises(ValueError, setattr, self.image, 'visibility', 'ellison') def test_tags_always_a_set(self): self.image.tags = ['a', 'b', 'c'] self.assertEqual(self.image.tags, set(['a', 'b', 'c'])) def test_delete_protected_image(self): self.image.protected = True self.assertRaises(exception.ProtectedImageDelete, self.image.delete) def test_status_saving(self): self.image.status = 'saving' self.assertEqual(self.image.status, 'saving') def test_status_saving_without_disk_format(self): self.image.disk_format = None self.assertRaises(ValueError, setattr, self.image, 'status', 'saving') def test_status_saving_without_container_format(self): self.image.container_format = None self.assertRaises(ValueError, setattr, self.image, 'status', 'saving') def test_status_active_without_disk_format(self): self.image.disk_format = None self.assertRaises(ValueError, setattr, self.image, 'status', 'active') def test_status_active_without_container_format(self): self.image.container_format = None self.assertRaises(ValueError, setattr, self.image, 'status', 'active') def test_delayed_delete(self): self.config(delayed_delete=True) self.image.status = 'active' self.image.locations = [{'url': 'http://foo.bar/not.exists', 'metadata': {}}] self.assertEqual(self.image.status, 'active') self.image.delete() self.assertEqual(self.image.status, 'pending_delete') class TestImageMember(test_utils.BaseTestCase): def setUp(self): super(TestImageMember, self).setUp() self.image_member_factory = domain.ImageMemberFactory() self.image_factory = domain.ImageFactory() self.image = self.image_factory.new_image() self.image_member = self.image_member_factory\ .new_image_member(image=self.image, member_id=TENANT1) def test_status_enumerated(self): self.image_member.status = 'pending' self.image_member.status = 'accepted' self.image_member.status = 'rejected' self.assertRaises(ValueError, setattr, self.image_member, 'status', 'ellison') class TestImageMemberFactory(test_utils.BaseTestCase): def setUp(self): super(TestImageMemberFactory, self).setUp() self.image_member_factory = domain.ImageMemberFactory() self.image_factory = domain.ImageFactory() def test_minimal_new_image_member(self): member_id = 'fake-member-id' image = self.image_factory.new_image( image_id=UUID1, name='image-1', min_disk=256, owner=TENANT1) image_member = self.image_member_factory.new_image_member(image, member_id) self.assertEqual(image_member.image_id, image.image_id) self.assertTrue(image_member.created_at is not None) self.assertEqual(image_member.created_at, image_member.updated_at) self.assertEqual(image_member.status, 'pending') self.assertTrue(image_member.member_id is not None) class TestExtraProperties(test_utils.BaseTestCase): def test_getitem(self): a_dict = {'foo': 'bar', 'snitch': 'golden'} extra_properties = domain.ExtraProperties(a_dict) self.assertEqual(extra_properties['foo'], 'bar') self.assertEqual(extra_properties['snitch'], 'golden') def test_getitem_with_no_items(self): extra_properties = domain.ExtraProperties() self.assertRaises(KeyError, extra_properties.__getitem__, 'foo') def test_setitem(self): a_dict = {'foo': 'bar', 'snitch': 'golden'} extra_properties = domain.ExtraProperties(a_dict) extra_properties['foo'] = 'baz' self.assertEqual(extra_properties['foo'], 'baz') def test_delitem(self): a_dict = {'foo': 'bar', 'snitch': 'golden'} extra_properties = domain.ExtraProperties(a_dict) del extra_properties['foo'] self.assertRaises(KeyError, extra_properties.__getitem__, 'foo') self.assertEqual(extra_properties['snitch'], 'golden') def test_len_with_zero_items(self): extra_properties = domain.ExtraProperties() self.assertEqual(len(extra_properties), 0) def test_len_with_non_zero_items(self): extra_properties = domain.ExtraProperties() extra_properties['foo'] = 'bar' extra_properties['snitch'] = 'golden' self.assertEqual(len(extra_properties), 2) def test_eq_with_a_dict(self): a_dict = {'foo': 'bar', 'snitch': 'golden'} extra_properties = domain.ExtraProperties(a_dict) ref_extra_properties = {'foo': 'bar', 'snitch': 'golden'} self.assertEqual(extra_properties, ref_extra_properties) def test_eq_with_an_object_of_ExtraProperties(self): a_dict = {'foo': 'bar', 'snitch': 'golden'} extra_properties = domain.ExtraProperties(a_dict) ref_extra_properties = domain.ExtraProperties() ref_extra_properties['snitch'] = 'golden' ref_extra_properties['foo'] = 'bar' self.assertEqual(extra_properties, ref_extra_properties) def test_eq_with_uneqal_dict(self): a_dict = {'foo': 'bar', 'snitch': 'golden'} extra_properties = domain.ExtraProperties(a_dict) ref_extra_properties = {'boo': 'far', 'gnitch': 'solden'} self.assertFalse(extra_properties.__eq__(ref_extra_properties)) def test_eq_with_unequal_ExtraProperties_object(self): a_dict = {'foo': 'bar', 'snitch': 'golden'} extra_properties = domain.ExtraProperties(a_dict) ref_extra_properties = domain.ExtraProperties() ref_extra_properties['gnitch'] = 'solden' ref_extra_properties['boo'] = 'far' self.assertFalse(extra_properties.__eq__(ref_extra_properties)) def test_eq_with_incompatible_object(self): a_dict = {'foo': 'bar', 'snitch': 'golden'} extra_properties = domain.ExtraProperties(a_dict) random_list = ['foo', 'bar'] self.assertFalse(extra_properties.__eq__(random_list)) class TestTaskFactory(test_utils.BaseTestCase): def setUp(self): super(TestTaskFactory, self).setUp() self.task_factory = domain.TaskFactory() def test_new_task(self): task_type = 'import' owner = TENANT1 task = self.task_factory.new_task(task_type, owner) self.assertTrue(task.task_id is not None) self.assertTrue(task.created_at is not None) self.assertEqual(task.created_at, task.updated_at) self.assertEqual(task.status, 'pending') self.assertEqual(task.owner, TENANT1) def test_new_task_invalid_type(self): task_type = 'blah' owner = TENANT1 self.assertRaises( exception.InvalidTaskType, self.task_factory.new_task, task_type, owner, ) def test_new_task_details(self): task_id = 'fake_task_id' task_input = '{"import_from": "fake"}' result = '{"result": "success"}' message = 'fake message' task_details = self.task_factory.new_task_details(task_id, task_input, message, result) self.assertEqual(task_details.task_id, task_id) self.assertEqual(task_details.input, task_input) self.assertEqual(task_details.result, result) self.assertEqual(task_details.message, message) class TestTask(test_utils.BaseTestCase): def setUp(self): super(TestTask, self).setUp() self.task_factory = domain.TaskFactory() task_type = 'import' owner = TENANT1 task_ttl = CONF.task.task_time_to_live self.gateway = unittest_utils.FakeGateway() self.task = self.task_factory.new_task(task_type, owner, task_time_to_live=task_ttl) def test_task_invalid_status(self): task_id = str(uuid.uuid4()) status = 'blah' self.assertRaises( exception.InvalidTaskStatus, domain.Task, task_id, task_type='import', status=status, owner=None, expires_at=None, created_at=timeutils.utcnow(), updated_at=timeutils.utcnow() ) def test_validate_status_transition_from_pending(self): self.task.begin_processing() self.assertEqual(self.task.status, 'processing') def test_validate_status_transition_from_processing_to_success(self): self.task.begin_processing() self.task.succeed('') self.assertEqual(self.task.status, 'success') def test_validate_status_transition_from_processing_to_failure(self): self.task.begin_processing() self.task.fail('') self.assertEqual(self.task.status, 'failure') def test_invalid_status_transitions_from_pending(self): #test do not allow transition from pending to success self.assertRaises( exception.InvalidTaskStatusTransition, self.task.succeed, '' ) def test_invalid_status_transitions_from_success(self): #test do not allow transition from success to processing self.task.begin_processing() self.task.succeed('') self.assertRaises( exception.InvalidTaskStatusTransition, self.task.begin_processing ) #test do not allow transition from success to failure self.assertRaises( exception.InvalidTaskStatusTransition, self.task.fail, '' ) def test_invalid_status_transitions_from_failure(self): #test do not allow transition from failure to processing self.task.begin_processing() self.task.fail('') self.assertRaises( exception.InvalidTaskStatusTransition, self.task.begin_processing ) #test do not allow transition from failure to success self.assertRaises( exception.InvalidTaskStatusTransition, self.task.succeed, '' ) def test_begin_processing(self): self.task.begin_processing() self.assertEqual(self.task.status, 'processing') @mock.patch.object(timeutils, 'utcnow') def test_succeed(self, mock_utcnow): mock_utcnow.return_value = datetime.datetime.utcnow() self.task.begin_processing() self.task.succeed('{"location": "file://home"}') self.assertEqual(self.task.status, 'success') expected = (timeutils.utcnow() + datetime.timedelta(hours=CONF.task.task_time_to_live)) self.assertEqual( self.task.expires_at, expected ) @mock.patch.object(timeutils, 'utcnow') def test_fail(self, mock_utcnow): mock_utcnow.return_value = datetime.datetime.utcnow() self.task.begin_processing() self.task.fail('{"message": "connection failed"}') self.assertEqual(self.task.status, 'failure') expected = (timeutils.utcnow() + datetime.timedelta(hours=CONF.task.task_time_to_live)) self.assertEqual( self.task.expires_at, expected ) class TestTaskDetails(test_utils.BaseTestCase): def setUp(self): super(TestTaskDetails, self).setUp() self.task_input = ('{"import_from": "file:///home/a.img",' ' "import_from_format": "qcow2"}') def test_task_details_init(self): task_details_values = ['task_id_1', self.task_input, 'result', 'None'] task_details = domain.TaskDetails(*task_details_values) self.assertIsNotNone(task_details) def test_task_details_with_no_task_id(self): task_id = None task_details_values = [task_id, self.task_input, 'result', 'None'] self.assertRaises(exception.TaskException, domain.TaskDetails, *task_details_values) glance-2014.1/glance/tests/unit/test_cinder_store.py0000664000175400017540000000646512323736226023654 0ustar jenkinsjenkins00000000000000# Copyright 2013 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import stubout from cinderclient.v2 import client as cinderclient from glance.common import exception from glance.openstack.common import units import glance.store.cinder as cinder from glance.store.location import get_location_from_uri from glance.tests.unit import base class FakeObject(object): def __init__(self, **kwargs): for name, value in kwargs.iteritems(): setattr(self, name, value) class TestCinderStore(base.StoreClearingUnitTest): def setUp(self): self.config(default_store='cinder', known_stores=['glance.store.cinder.Store']) super(TestCinderStore, self).setUp() self.stubs = stubout.StubOutForTesting() def test_cinder_configure_add(self): store = cinder.Store() self.assertRaises(exception.BadStoreConfiguration, store.configure_add) store = cinder.Store(context=None) self.assertRaises(exception.BadStoreConfiguration, store.configure_add) store = cinder.Store(context=FakeObject(service_catalog=None)) self.assertRaises(exception.BadStoreConfiguration, store.configure_add) store = cinder.Store(context=FakeObject(service_catalog= 'fake_service_catalog')) store.configure_add() def test_cinder_get_size(self): fake_client = FakeObject(auth_token=None, management_url=None) fake_volumes = {'12345678-9012-3455-6789-012345678901': FakeObject(size=5)} class FakeCinderClient(FakeObject): def __init__(self, *args, **kwargs): super(FakeCinderClient, self).__init__(client=fake_client, volumes=fake_volumes) self.stubs.Set(cinderclient, 'Client', FakeCinderClient) fake_sc = [{u'endpoints': [{u'publicURL': u'foo_public_url'}], u'endpoints_links': [], u'name': u'cinder', u'type': u'volume'}] fake_context = FakeObject(service_catalog=fake_sc, user='fake_uer', auth_tok='fake_token', tenant='fake_tenant') uri = 'cinder://%s' % fake_volumes.keys()[0] loc = get_location_from_uri(uri) store = cinder.Store(context=fake_context) image_size = store.get_size(loc) self.assertEqual(image_size, fake_volumes.values()[0].size * units.Gi) self.assertEqual(fake_client.auth_token, 'fake_token') self.assertEqual(fake_client.management_url, 'foo_public_url') glance-2014.1/glance/tests/unit/api/0000775000175400017540000000000012323736427020324 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/tests/unit/api/test_property_protections.py0000664000175400017540000003170512323736226026255 0ustar jenkinsjenkins00000000000000# Copyright 2013 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from glance.api import policy from glance.api import property_protections from glance.common import exception from glance.common import property_utils import glance.domain from glance.tests import utils TENANT1 = '6838eb7b-6ded-434a-882c-b344c77fe8df' TENANT2 = '2c014f32-55eb-467d-8fcb-4bd706012f81' class TestProtectedImageRepoProxy(utils.BaseTestCase): class ImageRepoStub(object): def __init__(self, fixtures): self.fixtures = fixtures def get(self, image_id): for f in self.fixtures: if f.image_id == image_id: return f else: raise ValueError(image_id) def list(self, *args, **kwargs): return self.fixtures def add(self, image): self.fixtures.append(image) def setUp(self): super(TestProtectedImageRepoProxy, self).setUp() self.set_property_protections() self.policy = policy.Enforcer() self.property_rules = property_utils.PropertyRules(self.policy) self.image_factory = glance.domain.ImageFactory() extra_props = {'spl_create_prop': 'c', 'spl_read_prop': 'r', 'spl_update_prop': 'u', 'spl_delete_prop': 'd', 'forbidden': 'prop'} extra_props_2 = {'spl_read_prop': 'r', 'forbidden': 'prop'} self.fixtures = [ self.image_factory.new_image(image_id='1', owner=TENANT1, extra_properties=extra_props), self.image_factory.new_image(owner=TENANT2, visibility='public'), self.image_factory.new_image(image_id='3', owner=TENANT1, extra_properties=extra_props_2), ] self.context = glance.context.RequestContext(roles=['spl_role']) image_repo = self.ImageRepoStub(self.fixtures) self.image_repo = property_protections.ProtectedImageRepoProxy( image_repo, self.context, self.property_rules) def test_get_image(self): image_id = '1' result_image = self.image_repo.get(image_id) result_extra_props = result_image.extra_properties self.assertEqual(result_extra_props['spl_create_prop'], 'c') self.assertEqual(result_extra_props['spl_read_prop'], 'r') self.assertEqual(result_extra_props['spl_update_prop'], 'u') self.assertEqual(result_extra_props['spl_delete_prop'], 'd') self.assertFalse('forbidden' in result_extra_props.keys()) def test_list_image(self): result_images = self.image_repo.list() self.assertEqual(len(result_images), 3) result_extra_props = result_images[0].extra_properties self.assertEqual(result_extra_props['spl_create_prop'], 'c') self.assertEqual(result_extra_props['spl_read_prop'], 'r') self.assertEqual(result_extra_props['spl_update_prop'], 'u') self.assertEqual(result_extra_props['spl_delete_prop'], 'd') self.assertFalse('forbidden' in result_extra_props.keys()) result_extra_props = result_images[1].extra_properties self.assertEqual(result_extra_props, {}) result_extra_props = result_images[2].extra_properties self.assertEqual(result_extra_props['spl_read_prop'], 'r') self.assertFalse('forbidden' in result_extra_props.keys()) class TestProtectedImageProxy(utils.BaseTestCase): def setUp(self): super(TestProtectedImageProxy, self).setUp() self.set_property_protections() self.policy = policy.Enforcer() self.property_rules = property_utils.PropertyRules(self.policy) class ImageStub(object): def __init__(self, extra_prop): self.extra_properties = extra_prop def test_read_image_with_extra_prop(self): context = glance.context.RequestContext(roles=['spl_role']) extra_prop = {'spl_read_prop': 'read', 'spl_fake_prop': 'prop'} image = self.ImageStub(extra_prop) result_image = property_protections.ProtectedImageProxy( image, context, self.property_rules) result_extra_props = result_image.extra_properties self.assertEqual(result_extra_props['spl_read_prop'], 'read') self.assertFalse('spl_fake_prop' in result_extra_props.keys()) class TestExtraPropertiesProxy(utils.BaseTestCase): def setUp(self): super(TestExtraPropertiesProxy, self).setUp() self.set_property_protections() self.policy = policy.Enforcer() self.property_rules = property_utils.PropertyRules(self.policy) def test_read_extra_property_as_admin_role(self): extra_properties = {'foo': 'bar', 'ping': 'pong'} context = glance.context.RequestContext(roles=['admin']) extra_prop_proxy = property_protections.ExtraPropertiesProxy( context, extra_properties, self.property_rules) test_result = extra_prop_proxy['foo'] self.assertEqual(test_result, 'bar') def test_read_extra_property_as_unpermitted_role(self): extra_properties = {'foo': 'bar', 'ping': 'pong'} context = glance.context.RequestContext(roles=['unpermitted_role']) extra_prop_proxy = property_protections.ExtraPropertiesProxy( context, extra_properties, self.property_rules) self.assertRaises(KeyError, extra_prop_proxy.__getitem__, 'foo') def test_update_extra_property_as_permitted_role_after_read(self): extra_properties = {'foo': 'bar', 'ping': 'pong'} context = glance.context.RequestContext(roles=['admin']) extra_prop_proxy = property_protections.ExtraPropertiesProxy( context, extra_properties, self.property_rules) extra_prop_proxy['foo'] = 'par' self.assertEqual(extra_prop_proxy['foo'], 'par') def test_update_extra_property_as_unpermitted_role_after_read(self): extra_properties = {'spl_read_prop': 'bar'} context = glance.context.RequestContext(roles=['spl_role']) extra_prop_proxy = property_protections.ExtraPropertiesProxy( context, extra_properties, self.property_rules) self.assertRaises(exception.ReservedProperty, extra_prop_proxy.__setitem__, 'spl_read_prop', 'par') def test_update_reserved_extra_property(self): extra_properties = {'spl_create_prop': 'bar'} context = glance.context.RequestContext(roles=['spl_role']) extra_prop_proxy = property_protections.ExtraPropertiesProxy( context, extra_properties, self.property_rules) self.assertRaises(exception.ReservedProperty, extra_prop_proxy.__setitem__, 'spl_create_prop', 'par') def test_create_extra_property_admin(self): extra_properties = {} context = glance.context.RequestContext(roles=['admin']) extra_prop_proxy = property_protections.ExtraPropertiesProxy( context, extra_properties, self.property_rules) extra_prop_proxy['boo'] = 'doo' self.assertEqual(extra_prop_proxy['boo'], 'doo') def test_create_reserved_extra_property(self): extra_properties = {} context = glance.context.RequestContext(roles=['spl_role']) extra_prop_proxy = property_protections.ExtraPropertiesProxy( context, extra_properties, self.property_rules) self.assertRaises(exception.ReservedProperty, extra_prop_proxy.__setitem__, 'boo', 'doo') def test_delete_extra_property_as_admin_role(self): extra_properties = {'foo': 'bar'} context = glance.context.RequestContext(roles=['admin']) extra_prop_proxy = property_protections.ExtraPropertiesProxy( context, extra_properties, self.property_rules) del extra_prop_proxy['foo'] self.assertRaises(KeyError, extra_prop_proxy.__getitem__, 'foo') def test_delete_nonexistant_extra_property_as_admin_role(self): extra_properties = {} context = glance.context.RequestContext(roles=['admin']) extra_prop_proxy = property_protections.ExtraPropertiesProxy( context, extra_properties, self.property_rules) self.assertRaises(KeyError, extra_prop_proxy.__delitem__, 'foo') def test_delete_reserved_extra_property(self): extra_properties = {'spl_read_prop': 'r'} context = glance.context.RequestContext(roles=['spl_role']) extra_prop_proxy = property_protections.ExtraPropertiesProxy( context, extra_properties, self.property_rules) # Ensure property has been created and can be read self.assertEqual(extra_prop_proxy['spl_read_prop'], 'r') self.assertRaises(exception.ReservedProperty, extra_prop_proxy.__delitem__, 'spl_read_prop') def test_delete_nonexistant_extra_property(self): extra_properties = {} roles = ['spl_role'] extra_prop_proxy = property_protections.ExtraPropertiesProxy( roles, extra_properties, self.property_rules) self.assertRaises(KeyError, extra_prop_proxy.__delitem__, 'spl_read_prop') class TestProtectedImageFactoryProxy(utils.BaseTestCase): def setUp(self): super(TestProtectedImageFactoryProxy, self).setUp() self.set_property_protections() self.policy = policy.Enforcer() self.property_rules = property_utils.PropertyRules(self.policy) self.factory = glance.domain.ImageFactory() def test_create_image_no_extra_prop(self): self.context = glance.context.RequestContext(tenant=TENANT1, roles=['spl_role']) self.image_factory = property_protections.ProtectedImageFactoryProxy( self.factory, self.context, self.property_rules) extra_props = {} image = self.image_factory.new_image(extra_properties=extra_props) expected_extra_props = {} self.assertEqual(image.extra_properties, expected_extra_props) def test_create_image_extra_prop(self): self.context = glance.context.RequestContext(tenant=TENANT1, roles=['spl_role']) self.image_factory = property_protections.ProtectedImageFactoryProxy( self.factory, self.context, self.property_rules) extra_props = {'spl_create_prop': 'c'} image = self.image_factory.new_image(extra_properties=extra_props) expected_extra_props = {'spl_create_prop': 'c'} self.assertEqual(image.extra_properties, expected_extra_props) def test_create_image_extra_prop_reserved_property(self): self.context = glance.context.RequestContext(tenant=TENANT1, roles=['spl_role']) self.image_factory = property_protections.ProtectedImageFactoryProxy( self.factory, self.context, self.property_rules) extra_props = {'foo': 'bar', 'spl_create_prop': 'c'} # no reg ex for property 'foo' is mentioned for spl_role in config self.assertRaises(exception.ReservedProperty, self.image_factory.new_image, extra_properties=extra_props) def test_create_image_extra_prop_admin(self): self.context = glance.context.RequestContext(tenant=TENANT1, roles=['admin']) self.image_factory = property_protections.ProtectedImageFactoryProxy( self.factory, self.context, self.property_rules) extra_props = {'foo': 'bar', 'spl_create_prop': 'c'} image = self.image_factory.new_image(extra_properties=extra_props) expected_extra_props = {'foo': 'bar', 'spl_create_prop': 'c'} self.assertEqual(image.extra_properties, expected_extra_props) def test_create_image_extra_prop_invalid_role(self): self.context = glance.context.RequestContext(tenant=TENANT1, roles=['imaginary-role']) self.image_factory = property_protections.ProtectedImageFactoryProxy( self.factory, self.context, self.property_rules) extra_props = {'foo': 'bar', 'spl_create_prop': 'c'} self.assertRaises(exception.ReservedProperty, self.image_factory.new_image, extra_properties=extra_props) glance-2014.1/glance/tests/unit/api/middleware/0000775000175400017540000000000012323736427022441 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/tests/unit/api/middleware/test_cache_manage.py0000664000175400017540000001364212323736226026430 0ustar jenkinsjenkins00000000000000# Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from glance.api import cached_images from glance.api.middleware import cache_manage import glance.common.config import glance.common.wsgi import glance.image_cache from glance.tests import utils as test_utils import mock import webob class TestCacheManageFilter(test_utils.BaseTestCase): @mock.patch.object(glance.image_cache.ImageCache, "init_driver") def setUp(self, mock_init_driver): super(TestCacheManageFilter, self).setUp() self.stub_application_name = "stubApplication" self.stub_value = "Stub value" self.image_id = "image_id_stub" mock_init_driver.return_value = None self.cache_manage_filter = cache_manage.CacheManageFilter( self.stub_application_name) def test_bogus_request(self): # prepare bogus_request = webob.Request.blank("/bogus/") # call resource = self.cache_manage_filter.process_request(bogus_request) #check self.assertIsNone(resource) @mock.patch.object(cached_images.Controller, "get_cached_images") def test_get_cached_images(self, mock_get_cached_images): # setup mock_get_cached_images.return_value = self.stub_value # prepare request = webob.Request.blank("/v1/cached_images") # call resource = self.cache_manage_filter.process_request(request) # check mock_get_cached_images.assert_called_with(request) self.assertEqual('"' + self.stub_value + '"', resource.body) @mock.patch.object(cached_images.Controller, "delete_cached_image") def test_delete_cached_image(self, mock_delete_cached_image): # setup mock_delete_cached_image.return_value = self.stub_value # prepare request = webob.Request.blank("/v1/cached_images/" + self.image_id, environ={'REQUEST_METHOD': "DELETE"}) # call resource = self.cache_manage_filter.process_request(request) # check mock_delete_cached_image.assert_called_with(request, image_id=self.image_id) self.assertEqual('"' + self.stub_value + '"', resource.body) @mock.patch.object(cached_images.Controller, "delete_cached_images") def test_delete_cached_images(self, mock_delete_cached_images): # setup mock_delete_cached_images.return_value = self.stub_value # prepare request = webob.Request.blank("/v1/cached_images", environ={'REQUEST_METHOD': "DELETE"}) # call resource = self.cache_manage_filter.process_request(request) # check mock_delete_cached_images.assert_called_with(request) self.assertEqual('"' + self.stub_value + '"', resource.body) @mock.patch.object(cached_images.Controller, "queue_image") def test_put_queued_image(self, mock_queue_image): # setup mock_queue_image.return_value = self.stub_value # prepare request = webob.Request.blank("/v1/queued_images/" + self.image_id, environ={'REQUEST_METHOD': "PUT"}) # call resource = self.cache_manage_filter.process_request(request) # check mock_queue_image.assert_called_with(request, image_id=self.image_id) self.assertEqual('"' + self.stub_value + '"', resource.body) @mock.patch.object(cached_images.Controller, "get_queued_images") def test_get_queued_images(self, mock_get_queued_images): # setup mock_get_queued_images.return_value = self.stub_value # prepare request = webob.Request.blank("/v1/queued_images") # call resource = self.cache_manage_filter.process_request(request) # check mock_get_queued_images.assert_called_with(request) self.assertEqual('"' + self.stub_value + '"', resource.body) @mock.patch.object(cached_images.Controller, "delete_queued_image") def test_delete_queued_image(self, mock_delete_queued_image): # setup mock_delete_queued_image.return_value = self.stub_value # prepare request = webob.Request.blank("/v1/queued_images/" + self.image_id, environ={'REQUEST_METHOD': 'DELETE'}) # call resource = self.cache_manage_filter.process_request(request) # check mock_delete_queued_image.assert_called_with(request, image_id=self.image_id) self.assertEqual('"' + self.stub_value + '"', resource.body) @mock.patch.object(cached_images.Controller, "delete_queued_images") def test_delete_queued_images(self, mock_delete_queued_images): # setup mock_delete_queued_images.return_value = self.stub_value # prepare request = webob.Request.blank("/v1/queued_images", environ={'REQUEST_METHOD': 'DELETE'}) # call resource = self.cache_manage_filter.process_request(request) # check mock_delete_queued_images.assert_called_with(request) self.assertEqual('"' + self.stub_value + '"', resource.body) glance-2014.1/glance/tests/unit/api/middleware/__init__.py0000664000175400017540000000000012323736226024535 0ustar jenkinsjenkins00000000000000glance-2014.1/glance/tests/unit/api/test_common.py0000664000175400017540000001307112323736226023224 0ustar jenkinsjenkins00000000000000# Copyright 2012 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import testtools import webob import glance.api.common from glance.common import config from glance.common import exception from glance.tests import utils as test_utils class SimpleIterator(object): def __init__(self, file_object, chunk_size): self.file_object = file_object self.chunk_size = chunk_size def __iter__(self): def read_chunk(): return self.fobj.read(self.chunk_size) chunk = read_chunk() while chunk: yield chunk chunk = read_chunk() else: raise StopIteration() class TestSizeCheckedIter(testtools.TestCase): def _get_image_metadata(self): return {'id': 'e31cb99c-fe89-49fb-9cc5-f5104fffa636'} def _get_webob_response(self): request = webob.Request.blank('/') response = webob.Response() response.request = request return response def test_uniform_chunk_size(self): resp = self._get_webob_response() meta = self._get_image_metadata() checked_image = glance.api.common.size_checked_iter( resp, meta, 4, ['AB', 'CD'], None) self.assertEqual('AB', checked_image.next()) self.assertEqual('CD', checked_image.next()) self.assertRaises(StopIteration, checked_image.next) def test_small_last_chunk(self): resp = self._get_webob_response() meta = self._get_image_metadata() checked_image = glance.api.common.size_checked_iter( resp, meta, 3, ['AB', 'C'], None) self.assertEqual('AB', checked_image.next()) self.assertEqual('C', checked_image.next()) self.assertRaises(StopIteration, checked_image.next) def test_variable_chunk_size(self): resp = self._get_webob_response() meta = self._get_image_metadata() checked_image = glance.api.common.size_checked_iter( resp, meta, 6, ['AB', '', 'CDE', 'F'], None) self.assertEqual('AB', checked_image.next()) self.assertEqual('', checked_image.next()) self.assertEqual('CDE', checked_image.next()) self.assertEqual('F', checked_image.next()) self.assertRaises(StopIteration, checked_image.next) def test_too_many_chunks(self): """An image should streamed regardless of expected_size""" resp = self._get_webob_response() meta = self._get_image_metadata() checked_image = glance.api.common.size_checked_iter( resp, meta, 4, ['AB', 'CD', 'EF'], None) self.assertEqual('AB', checked_image.next()) self.assertEqual('CD', checked_image.next()) self.assertEqual('EF', checked_image.next()) self.assertRaises(exception.GlanceException, checked_image.next) def test_too_few_chunks(self): resp = self._get_webob_response() meta = self._get_image_metadata() checked_image = glance.api.common.size_checked_iter(resp, meta, 6, ['AB', 'CD'], None) self.assertEqual('AB', checked_image.next()) self.assertEqual('CD', checked_image.next()) self.assertRaises(exception.GlanceException, checked_image.next) def test_too_much_data(self): resp = self._get_webob_response() meta = self._get_image_metadata() checked_image = glance.api.common.size_checked_iter(resp, meta, 3, ['AB', 'CD'], None) self.assertEqual('AB', checked_image.next()) self.assertEqual('CD', checked_image.next()) self.assertRaises(exception.GlanceException, checked_image.next) def test_too_little_data(self): resp = self._get_webob_response() meta = self._get_image_metadata() checked_image = glance.api.common.size_checked_iter(resp, meta, 6, ['AB', 'CD', 'E'], None) self.assertEqual('AB', checked_image.next()) self.assertEqual('CD', checked_image.next()) self.assertEqual('E', checked_image.next()) self.assertRaises(exception.GlanceException, checked_image.next) class TestMalformedRequest(test_utils.BaseTestCase): def setUp(self): """Establish a clean test environment""" super(TestMalformedRequest, self).setUp() self.config(flavor='', group='paste_deploy', config_file='etc/glance-api-paste.ini') self.api = config.load_paste_app('glance-api') def test_redirect_incomplete_url(self): """Test Glance redirects /v# to /v#/ with correct Location header""" req = webob.Request.blank('/v1.1') res = req.get_response(self.api) self.assertEqual(res.status_int, webob.exc.HTTPFound.code) self.assertEqual('http://localhost/v1/', res.location) glance-2014.1/glance/tests/unit/api/test_cmd_cache_manage.py0000664000175400017540000003604012323736226025133 0ustar jenkinsjenkins00000000000000# 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 optparse import mock from glance.cmd import cache_manage from glance.common import exception import glance.common.utils import glance.image_cache.client from glance.tests import utils as test_utils class TestGlanceCmdManage(test_utils.BaseTestCase): @mock.patch.object(glance.image_cache.client.CacheClient, 'get_cached_images') @mock.patch.object(glance.common.utils.PrettyTable, 'make_row') def test_list_cached_images(self, mock_row_create, mock_images): """ Verify that list_cached() method correctly processes images with all filled data and images with not filled 'last_accessed' field. """ mock_images.return_value = [ {'last_accessed': float(0), 'last_modified': float(1378985797.124511), 'image_id': '1', 'size': '128', 'hits': '1'}, {'last_accessed': float(1378985797.124511), 'last_modified': float(1378985797.124511), 'image_id': '2', 'size': '255', 'hits': '2'}] cache_manage.list_cached(mock.Mock(), '') self.assertEqual(len(mock_images.return_value), mock_row_create.call_count) @mock.patch.object(glance.image_cache.client.CacheClient, 'get_cached_images') def test_list_cached_images_empty(self, mock_images): """ Verify that list_cached() method handles a case when no images are cached without errors. """ mock_images.return_value = [] self.assertEqual(cache_manage.list_cached(mock.Mock(), ''), cache_manage.SUCCESS) @mock.patch.object(glance.image_cache.client.CacheClient, 'get_queued_images') @mock.patch.object(glance.common.utils.PrettyTable, 'make_row') def test_list_queued_images(self, mock_row_create, mock_images): """Verify that list_queued() method correctly processes images.""" mock_images.return_value = [ {'image_id': '1'}, {'image_id': '2'}] cache_manage.list_queued(mock.Mock(), '') self.assertEqual(len(mock_images.return_value), mock_row_create.call_count) @mock.patch.object(glance.image_cache.client.CacheClient, 'get_queued_images') def test_list_queued_images_empty(self, mock_images): """ Verify that list_queued() method handles a case when no images were queued without errors. """ mock_images.return_value = [] self.assertEqual(cache_manage.list_queued(mock.Mock(), ''), cache_manage.SUCCESS) def test_queue_image_without_index(self): self.assertEqual(cache_manage.queue_image(mock.Mock(), []), cache_manage.FAILURE) @mock.patch.object(glance.cmd.cache_manage, 'user_confirm') @mock.patch.object(glance.cmd.cache_manage, 'get_client') def test_queue_image_not_forced_not_confirmed(self, mock_client, mock_confirm): #options.forced set to False and queue confirmation set to False. mock_confirm.return_value = False mock_options = mock.Mock() mock_options.force = False self.assertEqual(cache_manage.queue_image(mock_options, ['img_id']), cache_manage.SUCCESS) self.assertFalse(mock_client.called) @mock.patch.object(glance.cmd.cache_manage, 'user_confirm') @mock.patch.object(glance.cmd.cache_manage, 'get_client') def test_queue_image_not_forced_confirmed(self, mock_client, mock_confirm): #options.forced set to False and queue confirmation set to True. mock_confirm.return_value = True mock_options = mock.Mock() mock_options.force = False mock_options.verbose = True # to cover additional condition and line manager = mock.MagicMock() manager.attach_mock(mock_client, 'mock_client') self.assertEqual(cache_manage.queue_image(mock_options, ['img_id']), cache_manage.SUCCESS) self.assertTrue(mock_client.called) self.assertTrue( mock.call.mock_client().queue_image_for_caching('img_id') in manager.mock_calls) def test_delete_cached_image_without_index(self): self.assertEqual(cache_manage.delete_cached_image(mock.Mock(), []), cache_manage.FAILURE) @mock.patch.object(glance.cmd.cache_manage, 'user_confirm') @mock.patch.object(glance.cmd.cache_manage, 'get_client') def test_delete_cached_image_not_forced_not_confirmed(self, mock_client, mock_confirm): #options.forced set to False and delete confirmation set to False. mock_confirm.return_value = False mock_options = mock.Mock() mock_options.force = False self.assertEqual( cache_manage.delete_cached_image(mock_options, ['img_id']), cache_manage.SUCCESS) self.assertFalse(mock_client.called) @mock.patch.object(glance.cmd.cache_manage, 'user_confirm') @mock.patch.object(glance.cmd.cache_manage, 'get_client') def test_delete_cached_image_not_forced_confirmed(self, mock_client, mock_confirm): #options.forced set to False and delete confirmation set to True. mock_confirm.return_value = True mock_options = mock.Mock() mock_options.force = False mock_options.verbose = True # to cover additional condition and line manager = mock.MagicMock() manager.attach_mock(mock_client, 'mock_client') self.assertEqual( cache_manage.delete_cached_image(mock_options, ['img_id']), cache_manage.SUCCESS) self.assertTrue( mock.call.mock_client().delete_cached_image('img_id') in manager.mock_calls) @mock.patch.object(glance.cmd.cache_manage, 'user_confirm') @mock.patch.object(glance.cmd.cache_manage, 'get_client') def test_delete_cached_images_not_forced_not_confirmed(self, mock_client, mock_confirm): #options.forced set to False and delete confirmation set to False. mock_confirm.return_value = False mock_options = mock.Mock() mock_options.force = False self.assertEqual( cache_manage.delete_all_cached_images(mock_options, None), cache_manage.SUCCESS) self.assertFalse(mock_client.called) @mock.patch.object(glance.cmd.cache_manage, 'user_confirm') @mock.patch.object(glance.cmd.cache_manage, 'get_client') def test_delete_cached_images_not_forced_confirmed(self, mock_client, mock_confirm): #options.forced set to False and delete confirmation set to True. mock_confirm.return_value = True mock_options = mock.Mock() mock_options.force = False mock_options.verbose = True # to cover additional condition and line manager = mock.MagicMock() manager.attach_mock(mock_client, 'mock_client') self.assertEqual( cache_manage.delete_all_cached_images(mock_options, None), cache_manage.SUCCESS) self.assertTrue(mock_client.called) self.assertTrue( mock.call.mock_client().delete_all_cached_images() in manager.mock_calls) def test_delete_queued_image_without_index(self): self.assertEqual(cache_manage.delete_queued_image(mock.Mock(), []), cache_manage.FAILURE) @mock.patch.object(glance.cmd.cache_manage, 'user_confirm') @mock.patch.object(glance.cmd.cache_manage, 'get_client') def test_delete_queued_image_not_forced_not_confirmed(self, mock_client, mock_confirm): #options.forced set to False and delete confirmation set to False. mock_confirm.return_value = False mock_options = mock.Mock() mock_options.force = False self.assertEqual( cache_manage.delete_queued_image(mock_options, ['img_id']), cache_manage.SUCCESS) self.assertFalse(mock_client.called) @mock.patch.object(glance.cmd.cache_manage, 'user_confirm') @mock.patch.object(glance.cmd.cache_manage, 'get_client') def test_delete_queued_image_not_forced_confirmed(self, mock_client, mock_confirm): #options.forced set to False and delete confirmation set to True. mock_confirm.return_value = True mock_options = mock.Mock() mock_options.force = False mock_options.verbose = True # to cover additional condition and line manager = mock.MagicMock() manager.attach_mock(mock_client, 'mock_client') self.assertEqual( cache_manage.delete_queued_image(mock_options, ['img_id']), cache_manage.SUCCESS) self.assertTrue(mock_client.called) self.assertTrue( mock.call.mock_client().delete_queued_image('img_id') in manager.mock_calls) @mock.patch.object(glance.cmd.cache_manage, 'user_confirm') @mock.patch.object(glance.cmd.cache_manage, 'get_client') def test_delete_queued_images_not_forced_not_confirmed(self, mock_client, mock_confirm): #options.forced set to False and delete confirmation set to False. mock_confirm.return_value = False mock_options = mock.Mock() mock_options.force = False self.assertEqual( cache_manage.delete_all_queued_images(mock_options, None), cache_manage.SUCCESS) self.assertFalse(mock_client.called) @mock.patch.object(glance.cmd.cache_manage, 'user_confirm') @mock.patch.object(glance.cmd.cache_manage, 'get_client') def test_delete_queued_images_not_forced_confirmed(self, mock_client, mock_confirm): #options.forced set to False and delete confirmation set to True. mock_confirm.return_value = True mock_options = mock.Mock() mock_options.force = False mock_options.verbose = True # to cover additional condition and line manager = mock.MagicMock() manager.attach_mock(mock_client, 'mock_client') self.assertEqual( cache_manage.delete_all_queued_images(mock_options, None), cache_manage.SUCCESS) self.assertTrue(mock_client.called) self.assertTrue( mock.call.mock_client().delete_all_queued_images() in manager.mock_calls) @mock.patch.object(glance.cmd.cache_manage, 'get_client') def test_catch_error_not_found(self, mock_function): mock_function.side_effect = exception.NotFound() self.assertEqual(cache_manage.list_cached(mock.Mock(), None), cache_manage.FAILURE) @mock.patch.object(glance.cmd.cache_manage, 'get_client') def test_catch_error_forbidden(self, mock_function): mock_function.side_effect = exception.Forbidden() self.assertEqual(cache_manage.list_cached(mock.Mock(), None), cache_manage.FAILURE) @mock.patch.object(glance.cmd.cache_manage, 'get_client') def test_catch_error_unhandled(self, mock_function): mock_function.side_effect = exception.Duplicate() my_mock = mock.Mock() my_mock.debug = False self.assertEqual(cache_manage.list_cached(my_mock, None), cache_manage.FAILURE) @mock.patch.object(glance.cmd.cache_manage, 'get_client') def test_catch_error_unhandled_debug_mode(self, mock_function): mock_function.side_effect = exception.Duplicate() my_mock = mock.Mock() my_mock.debug = True self.assertRaises(exception.Duplicate, cache_manage.list_cached, my_mock, None) def test_cache_manage_env(self): def_value = 'sometext12345678900987654321' self.assertNotEqual(def_value, cache_manage.env('PATH', default=def_value)) def test_cache_manage_env_default(self): def_value = 'sometext12345678900987654321' self.assertEqual(def_value, cache_manage.env('TMPVALUE1234567890', default=def_value)) def test_create_option(self): oparser = optparse.OptionParser() cache_manage.create_options(oparser) self.assertTrue(len(oparser.option_list) > 0) @mock.patch.object(glance.cmd.cache_manage, 'lookup_command') def test_parse_options_no_parameters(self, mock_lookup): oparser = optparse.OptionParser() cache_manage.create_options(oparser) result = self.assertRaises(SystemExit, cache_manage.parse_options, oparser, []) self.assertEqual(result.code, 0) self.assertFalse(mock_lookup.called) @mock.patch.object(optparse.OptionParser, 'print_usage') def test_parse_options_no_arguments(self, mock_printout): oparser = optparse.OptionParser() cache_manage.create_options(oparser) result = self.assertRaises(SystemExit, cache_manage.parse_options, oparser, ['-p', '1212']) self.assertEqual(result.code, 0) self.assertTrue(mock_printout.called) @mock.patch.object(glance.cmd.cache_manage, 'lookup_command') def test_parse_options_retrieve_command(self, mock_lookup): mock_lookup.return_value = True oparser = optparse.OptionParser() cache_manage.create_options(oparser) (options, command, args) = cache_manage.parse_options(oparser, ['-p', '1212', 'list-cached']) self.assertTrue(command) def test_lookup_command_unsupported_command(self): self.assertRaises(SystemExit, cache_manage.lookup_command, mock.Mock(), 'unsupported_command') def test_lookup_command_supported_command(self): command = cache_manage.lookup_command(mock.Mock(), 'list-cached') self.assertEqual(cache_manage.list_cached, command) glance-2014.1/glance/tests/unit/api/__init__.py0000664000175400017540000000000012323736226022420 0ustar jenkinsjenkins00000000000000glance-2014.1/glance/tests/unit/api/test_cmd.py0000664000175400017540000001300712323736226022476 0ustar jenkinsjenkins00000000000000# 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 mock import sys import six import glance.cmd.api import glance.cmd.cache_cleaner import glance.cmd.cache_pruner import glance.common.config from glance.common import exception as exc import glance.common.wsgi import glance.image_cache.cleaner import glance.image_cache.pruner from glance.tests import utils as test_utils class TestGlanceApiCmd(test_utils.BaseTestCase): __argv_backup = None def _do_nothing(self, *args, **kwargs): pass def _raise(self, exc): def fake(*args, **kwargs): raise exc return fake def setUp(self): super(TestGlanceApiCmd, self).setUp() self.__argv_backup = sys.argv sys.argv = ['glance-api'] self.stderr = six.StringIO() sys.stderr = self.stderr self.stubs.Set(glance.common.config, 'load_paste_app', self._do_nothing) self.stubs.Set(glance.common.wsgi.Server, 'start', self._do_nothing) self.stubs.Set(glance.common.wsgi.Server, 'wait', self._do_nothing) def tearDown(self): sys.stderr = sys.__stderr__ sys.argv = self.__argv_backup super(TestGlanceApiCmd, self).tearDown() def test_supported_default_store(self): self.config(default_store='file') glance.cmd.api.main() def test_unsupported_default_store(self): self.config(default_store='shouldnotexist') exit = self.assertRaises(SystemExit, glance.cmd.api.main) self.assertEqual(exit.code, 1) def test_worker_creation_failure(self): failure = exc.WorkerCreationFailure(reason='test') self.stubs.Set(glance.common.wsgi.Server, 'start', self._raise(failure)) exit = self.assertRaises(SystemExit, glance.cmd.api.main) self.assertEqual(exit.code, 2) @mock.patch.object(glance.common.config, 'parse_cache_args') @mock.patch.object(glance.openstack.common.log, 'setup') @mock.patch.object(glance.image_cache.ImageCache, 'init_driver') @mock.patch.object(glance.image_cache.ImageCache, 'clean') def test_cache_cleaner_main(self, mock_cache_clean, mock_cache_init_driver, mock_log_setup, mock_parse_config): mock_cache_init_driver.return_value = None manager = mock.MagicMock() manager.attach_mock(mock_log_setup, 'mock_log_setup') manager.attach_mock(mock_parse_config, 'mock_parse_config') manager.attach_mock(mock_cache_init_driver, 'mock_cache_init_driver') manager.attach_mock(mock_cache_clean, 'mock_cache_clean') glance.cmd.cache_cleaner.main() expected_call_sequence = [mock.call.mock_parse_config(), mock.call.mock_log_setup('glance'), mock.call.mock_cache_init_driver(), mock.call.mock_cache_clean()] self.assertEqual(expected_call_sequence, manager.mock_calls) @mock.patch.object(glance.image_cache.base.CacheApp, '__init__') def test_cache_cleaner_main_runtime_exception_handling(self, mock_cache): mock_cache.return_value = None self.stubs.Set(glance.image_cache.cleaner.Cleaner, 'run', self._raise(RuntimeError)) exit = self.assertRaises(SystemExit, glance.cmd.cache_cleaner.main) self.assertEqual('ERROR: ', exit.code) @mock.patch.object(glance.common.config, 'parse_cache_args') @mock.patch.object(glance.openstack.common.log, 'setup') @mock.patch.object(glance.image_cache.ImageCache, 'init_driver') @mock.patch.object(glance.image_cache.ImageCache, 'prune') def test_cache_pruner_main(self, mock_cache_prune, mock_cache_init_driver, mock_log_setup, mock_parse_config): mock_cache_init_driver.return_value = None manager = mock.MagicMock() manager.attach_mock(mock_log_setup, 'mock_log_setup') manager.attach_mock(mock_parse_config, 'mock_parse_config') manager.attach_mock(mock_cache_init_driver, 'mock_cache_init_driver') manager.attach_mock(mock_cache_prune, 'mock_cache_prune') glance.cmd.cache_pruner.main() expected_call_sequence = [mock.call.mock_parse_config(), mock.call.mock_log_setup('glance'), mock.call.mock_cache_init_driver(), mock.call.mock_cache_prune()] self.assertEqual(expected_call_sequence, manager.mock_calls) @mock.patch.object(glance.image_cache.base.CacheApp, '__init__') def test_cache_pruner_main_runtime_exception_handling(self, mock_cache): mock_cache.return_value = None self.stubs.Set(glance.image_cache.pruner.Pruner, 'run', self._raise(RuntimeError)) exit = self.assertRaises(SystemExit, glance.cmd.cache_pruner.main) self.assertEqual('ERROR: ', exit.code) glance-2014.1/glance/tests/unit/test_filesystem_store.py0000664000175400017540000004417312323736230024565 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """Tests the filesystem backend store""" import __builtin__ import errno import hashlib import json import os import uuid import fixtures import mox from oslo.config import cfg import six from glance.common import exception from glance.openstack.common import units from glance.store.filesystem import ChunkedFile from glance.store.filesystem import Store from glance.store.location import get_location_from_uri from glance.tests.unit import base CONF = cfg.CONF class TestStore(base.IsolatedUnitTest): def setUp(self): """Establish a clean test environment""" super(TestStore, self).setUp() self.orig_chunksize = ChunkedFile.CHUNKSIZE ChunkedFile.CHUNKSIZE = 10 self.store = Store() def tearDown(self): """Clear the test environment""" super(TestStore, self).tearDown() ChunkedFile.CHUNKSIZE = self.orig_chunksize def test_configure_add_single_datadir(self): """ Tests filesystem specified by filesystem_store_datadir are parsed correctly. """ store = self.useFixture(fixtures.TempDir()).path CONF.set_override('filesystem_store_datadir', store) self.store.configure_add() self.assertEqual(self.store.datadir, store) def test_configure_add_with_single_and_multi_datadirs(self): """ Tests BadStoreConfiguration exception is raised if both filesystem_store_datadir and filesystem_store_datadirs are specified. """ store_map = [self.useFixture(fixtures.TempDir()).path, self.useFixture(fixtures.TempDir()).path] CONF.set_override('filesystem_store_datadirs', [store_map[0] + ":100", store_map[1] + ":200"]) self.assertRaises(exception.BadStoreConfiguration, self.store.configure_add) def test_configure_add_without_single_and_multi_datadirs(self): """ Tests BadStoreConfiguration exception is raised if neither filesystem_store_datadir nor filesystem_store_datadirs are specified. """ CONF.clear_override('filesystem_store_datadir') self.assertRaises(exception.BadStoreConfiguration, self.store.configure_add) def test_configure_add_with_multi_datadirs(self): """ Tests multiple filesystem specified by filesystem_store_datadirs are parsed correctly. """ store_map = [self.useFixture(fixtures.TempDir()).path, self.useFixture(fixtures.TempDir()).path] CONF.clear_override('filesystem_store_datadir') CONF.set_override('filesystem_store_datadirs', [store_map[0] + ":100", store_map[1] + ":200"]) self.store.configure_add() expected_priority_map = {100: [store_map[0]], 200: [store_map[1]]} expected_priority_list = [200, 100] self.assertEqual(self.store.priority_data_map, expected_priority_map) self.assertEqual(self.store.priority_list, expected_priority_list) def test_configure_add_invalid_priority(self): """ Tests invalid priority specified by filesystem_store_datadirs param raises BadStoreConfiguration exception. """ CONF.clear_override('filesystem_store_datadir') CONF.set_override('filesystem_store_datadirs', [self.useFixture(fixtures.TempDir()).path + ":100", self.useFixture(fixtures.TempDir()).path + ":invalid"]) self.assertRaises(exception.BadStoreConfiguration, self.store.configure_add) def test_configure_add_same_dir_multiple_times(self): """ Tests BadStoreConfiguration exception is raised if same directory is specified multiple times in filesystem_store_datadirs. """ store_map = [self.useFixture(fixtures.TempDir()).path, self.useFixture(fixtures.TempDir()).path] CONF.clear_override('filesystem_store_datadir') CONF.set_override('filesystem_store_datadirs', [store_map[0] + ":100", store_map[1] + ":200", store_map[0] + ":300"]) self.assertRaises(exception.BadStoreConfiguration, self.store.configure_add) def test_configure_add_with_empty_datadir_path(self): """ Tests BadStoreConfiguration exception is raised if empty directory path is specified in filesystem_store_datadirs. """ CONF.clear_override('filesystem_store_datadir') CONF.set_override('filesystem_store_datadirs', ['']) self.assertRaises(exception.BadStoreConfiguration, self.store.configure_add) def test_configure_add_with_readonly_datadir_path(self): """ Tests BadStoreConfiguration exception is raised if directory path specified in filesystem_store_datadirs is readonly. """ readonly_dir = self.useFixture(fixtures.TempDir()).path os.chmod(readonly_dir, 0o444) CONF.clear_override('filesystem_store_datadir') CONF.set_override('filesystem_store_datadirs', [readonly_dir]) self.assertRaises(exception.BadStoreConfiguration, self.store.configure_add) def test_get(self): """Test a "normal" retrieval of an image in chunks""" # First add an image... image_id = str(uuid.uuid4()) file_contents = "chunk00000remainder" image_file = six.StringIO(file_contents) location, size, checksum, _ = self.store.add(image_id, image_file, len(file_contents)) # Now read it back... uri = "file:///%s/%s" % (self.test_dir, image_id) loc = get_location_from_uri(uri) (image_file, image_size) = self.store.get(loc) expected_data = "chunk00000remainder" expected_num_chunks = 2 data = "" num_chunks = 0 for chunk in image_file: num_chunks += 1 data += chunk self.assertEqual(expected_data, data) self.assertEqual(expected_num_chunks, num_chunks) def test_get_non_existing(self): """ Test that trying to retrieve a file that doesn't exist raises an error """ loc = get_location_from_uri("file:///%s/non-existing" % self.test_dir) self.assertRaises(exception.NotFound, self.store.get, loc) def test_add(self): """Test that we can add an image via the filesystem backend""" ChunkedFile.CHUNKSIZE = 1024 expected_image_id = str(uuid.uuid4()) expected_file_size = 5 * units.Ki # 5K expected_file_contents = "*" * expected_file_size expected_checksum = hashlib.md5(expected_file_contents).hexdigest() expected_location = "file://%s/%s" % (self.test_dir, expected_image_id) image_file = six.StringIO(expected_file_contents) location, size, checksum, _ = self.store.add(expected_image_id, image_file, expected_file_size) self.assertEqual(expected_location, location) self.assertEqual(expected_file_size, size) self.assertEqual(expected_checksum, checksum) uri = "file:///%s/%s" % (self.test_dir, expected_image_id) loc = get_location_from_uri(uri) (new_image_file, new_image_size) = self.store.get(loc) new_image_contents = "" new_image_file_size = 0 for chunk in new_image_file: new_image_file_size += len(chunk) new_image_contents += chunk self.assertEqual(expected_file_contents, new_image_contents) self.assertEqual(expected_file_size, new_image_file_size) def test_add_with_multiple_dirs(self): """Test adding multiple filesystem directories.""" store_map = [self.useFixture(fixtures.TempDir()).path, self.useFixture(fixtures.TempDir()).path] CONF.clear_override('filesystem_store_datadir') CONF.set_override('filesystem_store_datadirs', [store_map[0] + ":100", store_map[1] + ":200"]) self.store.configure_add() """Test that we can add an image via the filesystem backend""" ChunkedFile.CHUNKSIZE = 1024 expected_image_id = str(uuid.uuid4()) expected_file_size = 5 * units.Ki # 5K expected_file_contents = "*" * expected_file_size expected_checksum = hashlib.md5(expected_file_contents).hexdigest() expected_location = "file://%s/%s" % (store_map[1], expected_image_id) image_file = six.StringIO(expected_file_contents) location, size, checksum, _ = self.store.add(expected_image_id, image_file, expected_file_size) self.assertEqual(expected_location, location) self.assertEqual(expected_file_size, size) self.assertEqual(expected_checksum, checksum) loc = get_location_from_uri(expected_location) (new_image_file, new_image_size) = self.store.get(loc) new_image_contents = "" new_image_file_size = 0 for chunk in new_image_file: new_image_file_size += len(chunk) new_image_contents += chunk self.assertEqual(expected_file_contents, new_image_contents) self.assertEqual(expected_file_size, new_image_file_size) def test_add_with_multiple_dirs_storage_full(self): """ Test StorageFull exception is raised if no filesystem directory is found that can store an image. """ store_map = [self.useFixture(fixtures.TempDir()).path, self.useFixture(fixtures.TempDir()).path] CONF.clear_override('filesystem_store_datadir') CONF.set_override('filesystem_store_datadirs', [store_map[0] + ":100", store_map[1] + ":200"]) self.store.configure_add() def fake_get_capacity_info(mount_point): return 0 self.stubs.Set(self.store, '_get_capacity_info', fake_get_capacity_info) ChunkedFile.CHUNKSIZE = 1024 expected_image_id = str(uuid.uuid4()) expected_file_size = 5 * units.Ki # 5K expected_file_contents = "*" * expected_file_size image_file = six.StringIO(expected_file_contents) self.assertRaises(exception.StorageFull, self.store.add, expected_image_id, image_file, expected_file_size) def test_add_check_metadata_success(self): expected_image_id = str(uuid.uuid4()) in_metadata = {'akey': u'some value', 'list': [u'1', u'2', u'3']} jsonfilename = os.path.join(self.test_dir, "storage_metadata.%s" % expected_image_id) self.config(filesystem_store_metadata_file=jsonfilename) with open(jsonfilename, 'w') as fptr: json.dump(in_metadata, fptr) expected_file_size = 10 expected_file_contents = "*" * expected_file_size image_file = six.StringIO(expected_file_contents) location, size, checksum, metadata = self.store.add(expected_image_id, image_file, expected_file_size) self.assertEqual(metadata, in_metadata) def test_add_check_metadata_bad_data(self): expected_image_id = str(uuid.uuid4()) in_metadata = {'akey': 10} # only unicode is allowed jsonfilename = os.path.join(self.test_dir, "storage_metadata.%s" % expected_image_id) self.config(filesystem_store_metadata_file=jsonfilename) with open(jsonfilename, 'w') as fptr: json.dump(in_metadata, fptr) expected_file_size = 10 expected_file_contents = "*" * expected_file_size image_file = six.StringIO(expected_file_contents) location, size, checksum, metadata = self.store.add(expected_image_id, image_file, expected_file_size) self.assertEqual(metadata, {}) def test_add_check_metadata_bad_nosuch_file(self): expected_image_id = str(uuid.uuid4()) jsonfilename = os.path.join(self.test_dir, "storage_metadata.%s" % expected_image_id) self.config(filesystem_store_metadata_file=jsonfilename) expected_file_size = 10 expected_file_contents = "*" * expected_file_size image_file = six.StringIO(expected_file_contents) location, size, checksum, metadata = self.store.add(expected_image_id, image_file, expected_file_size) self.assertEqual(metadata, {}) def test_add_already_existing(self): """ Tests that adding an image with an existing identifier raises an appropriate exception """ ChunkedFile.CHUNKSIZE = 1024 image_id = str(uuid.uuid4()) file_size = 5 * units.Ki # 5K file_contents = "*" * file_size image_file = six.StringIO(file_contents) location, size, checksum, _ = self.store.add(image_id, image_file, file_size) image_file = six.StringIO("nevergonnamakeit") self.assertRaises(exception.Duplicate, self.store.add, image_id, image_file, 0) def _do_test_add_write_failure(self, errno, exception): ChunkedFile.CHUNKSIZE = 1024 image_id = str(uuid.uuid4()) file_size = 5 * units.Ki # 5K file_contents = "*" * file_size path = os.path.join(self.test_dir, image_id) image_file = six.StringIO(file_contents) m = mox.Mox() m.StubOutWithMock(__builtin__, 'open') e = IOError() e.errno = errno open(path, 'wb').AndRaise(e) m.ReplayAll() try: self.assertRaises(exception, self.store.add, image_id, image_file, 0) self.assertFalse(os.path.exists(path)) finally: m.VerifyAll() m.UnsetStubs() def test_add_storage_full(self): """ Tests that adding an image without enough space on disk raises an appropriate exception """ self._do_test_add_write_failure(errno.ENOSPC, exception.StorageFull) def test_add_file_too_big(self): """ Tests that adding an excessively large image file raises an appropriate exception """ self._do_test_add_write_failure(errno.EFBIG, exception.StorageFull) def test_add_storage_write_denied(self): """ Tests that adding an image with insufficient filestore permissions raises an appropriate exception """ self._do_test_add_write_failure(errno.EACCES, exception.StorageWriteDenied) def test_add_other_failure(self): """ Tests that a non-space-related IOError does not raise a StorageFull exception. """ self._do_test_add_write_failure(errno.ENOTDIR, IOError) def test_add_cleanup_on_read_failure(self): """ Tests the partial image file is cleaned up after a read failure. """ ChunkedFile.CHUNKSIZE = 1024 image_id = str(uuid.uuid4()) file_size = 5 * units.Ki # 5K file_contents = "*" * file_size path = os.path.join(self.test_dir, image_id) image_file = six.StringIO(file_contents) def fake_Error(size): raise AttributeError() self.stubs.Set(image_file, 'read', fake_Error) self.assertRaises(AttributeError, self.store.add, image_id, image_file, 0) self.assertFalse(os.path.exists(path)) def test_delete(self): """ Test we can delete an existing image in the filesystem store """ # First add an image image_id = str(uuid.uuid4()) file_size = 5 * units.Ki # 5K file_contents = "*" * file_size image_file = six.StringIO(file_contents) location, size, checksum, _ = self.store.add(image_id, image_file, file_size) # Now check that we can delete it uri = "file:///%s/%s" % (self.test_dir, image_id) loc = get_location_from_uri(uri) self.store.delete(loc) self.assertRaises(exception.NotFound, self.store.get, loc) def test_delete_non_existing(self): """ Test that trying to delete a file that doesn't exist raises an error """ loc = get_location_from_uri("file:///tmp/glance-tests/non-existing") self.assertRaises(exception.NotFound, self.store.delete, loc) glance-2014.1/glance/tests/unit/test_domain_proxy.py0000664000175400017540000002736312323736226023704 0ustar jenkinsjenkins00000000000000# Copyright 2013 OpenStack Foundation. # Copyright 2013 IBM Corp. # 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 mock from six.moves import xrange from glance.domain import proxy import glance.tests.utils as test_utils UUID1 = 'c80a1a6c-bd1f-41c5-90ee-81afedb1d58d' TENANT1 = '6838eb7b-6ded-434a-882c-b344c77fe8df' class FakeProxy(object): def __init__(self, base, *args, **kwargs): self.base = base self.args = args self.kwargs = kwargs class FakeRepo(object): def __init__(self, result=None): self.args = None self.kwargs = None self.result = result def fake_method(self, *args, **kwargs): self.args = args self.kwargs = kwargs return self.result get = fake_method list = fake_method add = fake_method save = fake_method remove = fake_method class TestProxyRepoPlain(test_utils.BaseTestCase): def setUp(self): super(TestProxyRepoPlain, self).setUp() self.fake_repo = FakeRepo() self.proxy_repo = proxy.Repo(self.fake_repo) def _test_method(self, name, base_result, *args, **kwargs): self.fake_repo.result = base_result method = getattr(self.proxy_repo, name) proxy_result = method(*args, **kwargs) self.assertEqual(proxy_result, base_result) self.assertEqual(self.fake_repo.args, args) self.assertEqual(self.fake_repo.kwargs, kwargs) def test_get(self): self._test_method('get', 'snarf', 'abcd') def test_list(self): self._test_method('list', ['sniff', 'snarf'], 2, filter='^sn') def test_add(self): self._test_method('add', 'snuff', 'enough') def test_save(self): self._test_method('save', 'snuff', 'enough') def test_remove(self): self._test_method('add', None, 'flying') class TestProxyRepoWrapping(test_utils.BaseTestCase): def setUp(self): super(TestProxyRepoWrapping, self).setUp() self.fake_repo = FakeRepo() self.proxy_repo = proxy.Repo(self.fake_repo, item_proxy_class=FakeProxy, item_proxy_kwargs={'a': 1}) def _test_method(self, name, base_result, *args, **kwargs): self.fake_repo.result = base_result method = getattr(self.proxy_repo, name) proxy_result = method(*args, **kwargs) self.assertIsInstance(proxy_result, FakeProxy) self.assertEqual(proxy_result.base, base_result) self.assertEqual(len(proxy_result.args), 0) self.assertEqual(proxy_result.kwargs, {'a': 1}) self.assertEqual(self.fake_repo.args, args) self.assertEqual(self.fake_repo.kwargs, kwargs) def test_get(self): self.fake_repo.result = 'snarf' result = self.proxy_repo.get('some-id') self.assertIsInstance(result, FakeProxy) self.assertEqual(self.fake_repo.args, ('some-id',)) self.assertEqual(self.fake_repo.kwargs, {}) self.assertEqual(result.base, 'snarf') self.assertEqual(result.args, tuple()) self.assertEqual(result.kwargs, {'a': 1}) def test_list(self): self.fake_repo.result = ['scratch', 'sniff'] results = self.proxy_repo.list(2, prefix='s') self.assertEqual(self.fake_repo.args, (2,)) self.assertEqual(self.fake_repo.kwargs, {'prefix': 's'}) self.assertEqual(len(results), 2) for i in xrange(2): self.assertIsInstance(results[i], FakeProxy) self.assertEqual(results[i].base, self.fake_repo.result[i]) self.assertEqual(results[i].args, tuple()) self.assertEqual(results[i].kwargs, {'a': 1}) def _test_method_with_proxied_argument(self, name, result): self.fake_repo.result = result item = FakeProxy('snoop') method = getattr(self.proxy_repo, name) proxy_result = method(item) self.assertEqual(self.fake_repo.args, ('snoop',)) self.assertEqual(self.fake_repo.kwargs, {}) if result is None: self.assertTrue(proxy_result is None) else: self.assertIsInstance(proxy_result, FakeProxy) self.assertEqual(proxy_result.base, result) self.assertEqual(proxy_result.args, tuple()) self.assertEqual(proxy_result.kwargs, {'a': 1}) def test_add(self): self._test_method_with_proxied_argument('add', 'dog') def test_add_with_no_result(self): self._test_method_with_proxied_argument('add', None) def test_save(self): self._test_method_with_proxied_argument('save', 'dog') def test_save_with_no_result(self): self._test_method_with_proxied_argument('save', None) def test_remove(self): self._test_method_with_proxied_argument('remove', 'dog') def test_remove_with_no_result(self): self._test_method_with_proxied_argument('remove', None) class FakeImageFactory(object): def __init__(self, result=None): self.result = None self.kwargs = None def new_image(self, **kwargs): self.kwargs = kwargs return self.result class TestImageFactory(test_utils.BaseTestCase): def setUp(self): super(TestImageFactory, self).setUp() self.factory = FakeImageFactory() def test_proxy_plain(self): proxy_factory = proxy.ImageFactory(self.factory) self.factory.result = 'eddard' image = proxy_factory.new_image(a=1, b='two') self.assertEqual(image, 'eddard') self.assertEqual(self.factory.kwargs, {'a': 1, 'b': 'two'}) def test_proxy_wrapping(self): proxy_factory = proxy.ImageFactory(self.factory, proxy_class=FakeProxy, proxy_kwargs={'dog': 'bark'}) self.factory.result = 'stark' image = proxy_factory.new_image(a=1, b='two') self.assertIsInstance(image, FakeProxy) self.assertEqual(image.base, 'stark') self.assertEqual(self.factory.kwargs, {'a': 1, 'b': 'two'}) class FakeImageMembershipFactory(object): def __init__(self, result=None): self.result = None self.image = None self.member_id = None def new_image_member(self, image, member_id): self.image = image self.member_id = member_id return self.result class TestImageMembershipFactory(test_utils.BaseTestCase): def setUp(self): super(TestImageMembershipFactory, self).setUp() self.factory = FakeImageMembershipFactory() def test_proxy_plain(self): proxy_factory = proxy.ImageMembershipFactory(self.factory) self.factory.result = 'tyrion' membership = proxy_factory.new_image_member('jaime', 'cersei') self.assertEqual(membership, 'tyrion') self.assertEqual(self.factory.image, 'jaime') self.assertEqual(self.factory.member_id, 'cersei') def test_proxy_wrapped_membership(self): proxy_factory = proxy.ImageMembershipFactory( self.factory, member_proxy_class=FakeProxy, member_proxy_kwargs={'a': 1}) self.factory.result = 'tyrion' membership = proxy_factory.new_image_member('jaime', 'cersei') self.assertIsInstance(membership, FakeProxy) self.assertEqual(membership.base, 'tyrion') self.assertEqual(membership.kwargs, {'a': 1}) self.assertEqual(self.factory.image, 'jaime') self.assertEqual(self.factory.member_id, 'cersei') def test_proxy_wrapped_image(self): proxy_factory = proxy.ImageMembershipFactory( self.factory, image_proxy_class=FakeProxy) self.factory.result = 'tyrion' image = FakeProxy('jaime') membership = proxy_factory.new_image_member(image, 'cersei') self.assertEqual(membership, 'tyrion') self.assertEqual(self.factory.image, 'jaime') self.assertEqual(self.factory.member_id, 'cersei') def test_proxy_both_wrapped(self): class FakeProxy2(FakeProxy): pass proxy_factory = proxy.ImageMembershipFactory( self.factory, member_proxy_class=FakeProxy, member_proxy_kwargs={'b': 2}, image_proxy_class=FakeProxy2) self.factory.result = 'tyrion' image = FakeProxy2('jaime') membership = proxy_factory.new_image_member(image, 'cersei') self.assertIsInstance(membership, FakeProxy) self.assertEqual(membership.base, 'tyrion') self.assertEqual(membership.kwargs, {'b': 2}) self.assertEqual(self.factory.image, 'jaime') self.assertEqual(self.factory.member_id, 'cersei') class FakeImage(object): def __init__(self, result=None): self.result = result def get_member_repo(self): return self.result class TestImage(test_utils.BaseTestCase): def setUp(self): super(TestImage, self).setUp() self.image = FakeImage() def test_normal_member_repo(self): proxy_image = proxy.Image(self.image) self.image.result = 'mormont' self.assertEqual(proxy_image.get_member_repo(), 'mormont') def test_proxied_member_repo(self): proxy_image = proxy.Image(self.image, member_repo_proxy_class=FakeProxy, member_repo_proxy_kwargs={'a': 10}) self.image.result = 'corn' member_repo = proxy_image.get_member_repo() self.assertIsInstance(member_repo, FakeProxy) self.assertEqual(member_repo.base, 'corn') class TestTaskFactory(test_utils.BaseTestCase): def setUp(self): super(TestTaskFactory, self).setUp() self.factory = mock.Mock() self.fake_type = 'import' self.fake_owner = "owner" def test_proxy_plain(self): proxy_factory = proxy.TaskFactory(self.factory) proxy_factory.new_task( type=self.fake_type, owner=self.fake_owner ) self.factory.new_task.assert_called_once_with( type=self.fake_type, owner=self.fake_owner ) proxy_factory.new_task_details("task_01", "input") self.factory.new_task_details.assert_called_once_with( "task_01", "input", None, None ) def test_proxy_wrapping(self): proxy_factory = proxy.TaskFactory( self.factory, task_proxy_class=FakeProxy, task_proxy_kwargs={'dog': 'bark'}, task_details_proxy_class=FakeProxy, task_details_proxy_kwargs={'dog': 'bark'}) self.factory.new_task.return_value = 'fake_task' self.factory.new_task_details.return_value = 'fake_task_detail' task = proxy_factory.new_task( type=self.fake_type, owner=self.fake_owner ) self.factory.new_task.assert_called_once_with( type=self.fake_type, owner=self.fake_owner ) self.assertIsInstance(task, FakeProxy) self.assertEqual(task.base, 'fake_task') task_details = proxy_factory.new_task_details('task_01', "input") self.factory.new_task_details.assert_called_once_with( 'task_01', "input", None, None ) self.assertIsInstance(task_details, FakeProxy) self.assertEqual(task_details.base, 'fake_task_detail') glance-2014.1/glance/tests/unit/test_context.py0000664000175400017540000001442412323736226022652 0ustar jenkinsjenkins00000000000000# Copyright 2010-2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from glance import context from glance.openstack.common import local from glance.tests.unit import utils as unit_utils from glance.tests import utils def _fake_image(owner, is_public): return { 'id': None, 'owner': owner, 'is_public': is_public, } def _fake_membership(can_share=False): return {'can_share': can_share} class TestContext(utils.BaseTestCase): def setUp(self): super(TestContext, self).setUp() self.db_api = unit_utils.FakeDB() def do_visible(self, exp_res, img_owner, img_public, **kwargs): """ Perform a context visibility test. Creates a (fake) image with the specified owner and is_public attributes, then creates a context with the given keyword arguments and expects exp_res as the result of an is_image_visible() call on the context. """ img = _fake_image(img_owner, img_public) ctx = context.RequestContext(**kwargs) self.assertEqual(self.db_api.is_image_visible(ctx, img), exp_res) def test_empty_public(self): """ Tests that an empty context (with is_admin set to True) can access an image with is_public set to True. """ self.do_visible(True, None, True, is_admin=True) def test_empty_public_owned(self): """ Tests that an empty context (with is_admin set to True) can access an owned image with is_public set to True. """ self.do_visible(True, 'pattieblack', True, is_admin=True) def test_empty_private(self): """ Tests that an empty context (with is_admin set to True) can access an image with is_public set to False. """ self.do_visible(True, None, False, is_admin=True) def test_empty_private_owned(self): """ Tests that an empty context (with is_admin set to True) can access an owned image with is_public set to False. """ self.do_visible(True, 'pattieblack', False, is_admin=True) def test_anon_public(self): """ Tests that an anonymous context (with is_admin set to False) can access an image with is_public set to True. """ self.do_visible(True, None, True) def test_anon_public_owned(self): """ Tests that an anonymous context (with is_admin set to False) can access an owned image with is_public set to True. """ self.do_visible(True, 'pattieblack', True) def test_anon_private(self): """ Tests that an anonymous context (with is_admin set to False) can access an unowned image with is_public set to False. """ self.do_visible(True, None, False) def test_anon_private_owned(self): """ Tests that an anonymous context (with is_admin set to False) cannot access an owned image with is_public set to False. """ self.do_visible(False, 'pattieblack', False) def test_auth_public(self): """ Tests that an authenticated context (with is_admin set to False) can access an image with is_public set to True. """ self.do_visible(True, None, True, tenant='froggy') def test_auth_public_unowned(self): """ Tests that an authenticated context (with is_admin set to False) can access an image (which it does not own) with is_public set to True. """ self.do_visible(True, 'pattieblack', True, tenant='froggy') def test_auth_public_owned(self): """ Tests that an authenticated context (with is_admin set to False) can access an image (which it does own) with is_public set to True. """ self.do_visible(True, 'pattieblack', True, tenant='pattieblack') def test_auth_private(self): """ Tests that an authenticated context (with is_admin set to False) can access an image with is_public set to False. """ self.do_visible(True, None, False, tenant='froggy') def test_auth_private_unowned(self): """ Tests that an authenticated context (with is_admin set to False) cannot access an image (which it does not own) with is_public set to False. """ self.do_visible(False, 'pattieblack', False, tenant='froggy') def test_auth_private_owned(self): """ Tests that an authenticated context (with is_admin set to False) can access an image (which it does own) with is_public set to False. """ self.do_visible(True, 'pattieblack', False, tenant='pattieblack') def test_request_id(self): contexts = [context.RequestContext().request_id for _ in range(5)] # Check for uniqueness -- set() will normalize its argument self.assertEqual(5, len(set(contexts))) def test_service_catalog(self): ctx = context.RequestContext(service_catalog=['foo']) self.assertEqual(['foo'], ctx.service_catalog) def test_context_local_store(self): if hasattr(local.store, 'context'): del local.store.context ctx = context.RequestContext() self.assertTrue(hasattr(local.store, 'context')) self.assertEqual(ctx, local.store.context) def test_user_identity(self): ctx = context.RequestContext(user="user", tenant="tenant", domain="domain", user_domain="user-domain", project_domain="project-domain") self.assertEqual('user tenant domain user-domain project-domain', ctx.to_dict()["user_identity"]) glance-2014.1/glance/tests/unit/test_http_store.py0000664000175400017540000001631012323736226023355 0ustar jenkinsjenkins00000000000000# Copyright 2010-2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from six.moves import xrange import stubout from glance.common import exception from glance import context from glance.db.sqlalchemy import api as db_api from glance.registry.client.v1.api import configure_registry_client from glance.store import delete_from_backend from glance.store.http import MAX_REDIRECTS from glance.store.http import Store from glance.store.location import get_location_from_uri from glance.store import safe_delete_from_backend from glance.tests import stubs as test_stubs from glance.tests.unit import base from glance.tests import utils # The response stack is used to return designated responses in order; # however when it's empty a default 200 OK response is returned from # FakeHTTPConnection below. FAKE_RESPONSE_STACK = [] def stub_out_http_backend(stubs): """ Stubs out the httplib.HTTPRequest.getresponse to return faked-out data instead of grabbing actual contents of a resource The stubbed getresponse() returns an iterator over the data "I am a teapot, short and stout\n" :param stubs: Set of stubout stubs """ class FakeHTTPConnection(object): def __init__(self, *args, **kwargs): pass def getresponse(self): if len(FAKE_RESPONSE_STACK): return FAKE_RESPONSE_STACK.pop() return utils.FakeHTTPResponse() def request(self, *_args, **_kwargs): pass def close(self): pass def fake_get_conn_class(self, *args, **kwargs): return FakeHTTPConnection stubs.Set(Store, '_get_conn_class', fake_get_conn_class) def stub_out_registry_image_update(stubs): """ Stubs an image update on the registry. :param stubs: Set of stubout stubs """ test_stubs.stub_out_registry_server(stubs) def fake_image_update(ctx, image_id, values, purge_props=False): return {'properties': {}} stubs.Set(db_api, 'image_update', fake_image_update) class TestHttpStore(base.StoreClearingUnitTest): def setUp(self): global FAKE_RESPONSE_STACK FAKE_RESPONSE_STACK = [] self.config(default_store='http', known_stores=['glance.store.http.Store']) super(TestHttpStore, self).setUp() self.stubs = stubout.StubOutForTesting() stub_out_http_backend(self.stubs) Store.CHUNKSIZE = 2 self.store = Store() configure_registry_client() def test_http_get(self): uri = "http://netloc/path/to/file.tar.gz" expected_returns = ['I ', 'am', ' a', ' t', 'ea', 'po', 't,', ' s', 'ho', 'rt', ' a', 'nd', ' s', 'to', 'ut', '\n'] loc = get_location_from_uri(uri) (image_file, image_size) = self.store.get(loc) self.assertEqual(image_size, 31) chunks = [c for c in image_file] self.assertEqual(chunks, expected_returns) def test_http_get_redirect(self): # Add two layers of redirects to the response stack, which will # return the default 200 OK with the expected data after resolving # both redirects. redirect_headers_1 = {"location": "http://example.com/teapot.img"} redirect_resp_1 = utils.FakeHTTPResponse(status=302, headers=redirect_headers_1) redirect_headers_2 = {"location": "http://example.com/teapot_real.img"} redirect_resp_2 = utils.FakeHTTPResponse(status=301, headers=redirect_headers_2) FAKE_RESPONSE_STACK.append(redirect_resp_1) FAKE_RESPONSE_STACK.append(redirect_resp_2) uri = "http://netloc/path/to/file.tar.gz" expected_returns = ['I ', 'am', ' a', ' t', 'ea', 'po', 't,', ' s', 'ho', 'rt', ' a', 'nd', ' s', 'to', 'ut', '\n'] loc = get_location_from_uri(uri) (image_file, image_size) = self.store.get(loc) self.assertEqual(image_size, 31) chunks = [c for c in image_file] self.assertEqual(chunks, expected_returns) def test_http_get_max_redirects(self): # Add more than MAX_REDIRECTS redirects to the response stack redirect_headers = {"location": "http://example.com/teapot.img"} redirect_resp = utils.FakeHTTPResponse(status=302, headers=redirect_headers) for i in xrange(MAX_REDIRECTS + 2): FAKE_RESPONSE_STACK.append(redirect_resp) uri = "http://netloc/path/to/file.tar.gz" loc = get_location_from_uri(uri) self.assertRaises(exception.MaxRedirectsExceeded, self.store.get, loc) def test_http_get_redirect_invalid(self): redirect_headers = {"location": "http://example.com/teapot.img"} redirect_resp = utils.FakeHTTPResponse(status=307, headers=redirect_headers) FAKE_RESPONSE_STACK.append(redirect_resp) uri = "http://netloc/path/to/file.tar.gz" loc = get_location_from_uri(uri) self.assertRaises(exception.BadStoreUri, self.store.get, loc) def test_http_get_not_found(self): not_found_resp = utils.FakeHTTPResponse(status=404, data="404 Not Found") FAKE_RESPONSE_STACK.append(not_found_resp) uri = "http://netloc/path/to/file.tar.gz" loc = get_location_from_uri(uri) self.assertRaises(exception.BadStoreUri, self.store.get, loc) def test_https_get(self): uri = "https://netloc/path/to/file.tar.gz" expected_returns = ['I ', 'am', ' a', ' t', 'ea', 'po', 't,', ' s', 'ho', 'rt', ' a', 'nd', ' s', 'to', 'ut', '\n'] loc = get_location_from_uri(uri) (image_file, image_size) = self.store.get(loc) self.assertEqual(image_size, 31) chunks = [c for c in image_file] self.assertEqual(chunks, expected_returns) def test_http_delete_raise_error(self): uri = "https://netloc/path/to/file.tar.gz" loc = get_location_from_uri(uri) ctx = context.RequestContext() self.assertRaises(NotImplementedError, self.store.delete, loc) self.assertRaises(exception.StoreDeleteNotSupported, delete_from_backend, ctx, uri) def test_http_schedule_delete_swallows_error(self): uri = "https://netloc/path/to/file.tar.gz" ctx = context.RequestContext() stub_out_registry_image_update(self.stubs) try: safe_delete_from_backend(ctx, uri, 'image_id') except exception.StoreDeleteNotSupported: self.fail('StoreDeleteNotSupported should be swallowed') glance-2014.1/glance/tests/unit/test_store_location.py0000664000175400017540000004733712323736226024223 0ustar jenkinsjenkins00000000000000# Copyright 2011-2013 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import mock from glance.common import exception from glance import context import glance.store import glance.store.filesystem import glance.store.http import glance.store.location as location import glance.store.s3 import glance.store.swift import glance.store.vmware_datastore from glance.tests.unit import base class TestStoreLocation(base.StoreClearingUnitTest): def setUp(self): self.config(default_store='file') # NOTE(flaper87): Each store should test # this in their test suite. self.config(known_stores=[ "glance.store.filesystem.Store", "glance.store.http.Store", "glance.store.rbd.Store", "glance.store.s3.Store", "glance.store.swift.Store", "glance.store.sheepdog.Store", "glance.store.cinder.Store", "glance.store.gridfs.Store", "glance.store.vmware_datastore.Store", ]) super(TestStoreLocation, self).setUp() def test_get_location_from_uri_back_to_uri(self): """ Test that for various URIs, the correct Location object can be contructed and then the original URI returned via the get_store_uri() method. """ good_store_uris = [ 'https://user:pass@example.com:80/images/some-id', 'http://images.oracle.com/123456', 'swift://account%3Auser:pass@authurl.com/container/obj-id', 'swift://storeurl.com/container/obj-id', 'swift+https://account%3Auser:pass@authurl.com/container/obj-id', 's3://accesskey:secretkey@s3.amazonaws.com/bucket/key-id', 's3://accesskey:secretwith/aslash@s3.amazonaws.com/bucket/key-id', 's3+http://accesskey:secret@s3.amazonaws.com/bucket/key-id', 's3+https://accesskey:secretkey@s3.amazonaws.com/bucket/key-id', 'file:///var/lib/glance/images/1', 'rbd://imagename', 'rbd://fsid/pool/image/snap', 'rbd://%2F/%2F/%2F/%2F', 'sheepdog://244e75f1-9c69-4167-9db7-1aa7d1973f6c', 'cinder://12345678-9012-3455-6789-012345678901', 'vsphere://ip/folder/openstack_glance/2332298?dcPath=dc&dsName=ds', ] for uri in good_store_uris: loc = location.get_location_from_uri(uri) # The get_store_uri() method *should* return an identical URI # to the URI that is passed to get_location_from_uri() self.assertEqual(loc.get_store_uri(), uri) def test_bad_store_scheme(self): """ Test that a URI with a non-existing scheme triggers exception """ bad_uri = 'unknown://user:pass@example.com:80/images/some-id' self.assertRaises(exception.UnknownScheme, location.get_location_from_uri, bad_uri) def test_filesystem_store_location(self): """ Test the specific StoreLocation for the Filesystem store """ uri = 'file:///var/lib/glance/images/1' loc = glance.store.filesystem.StoreLocation({}) loc.parse_uri(uri) self.assertEqual("file", loc.scheme) self.assertEqual("/var/lib/glance/images/1", loc.path) self.assertEqual(uri, loc.get_uri()) bad_uri = 'fil://' self.assertRaises(AssertionError, loc.parse_uri, bad_uri) bad_uri = 'file://' self.assertRaises(exception.BadStoreUri, loc.parse_uri, bad_uri) def test_http_store_location(self): """ Test the specific StoreLocation for the HTTP store """ uri = 'http://example.com/images/1' loc = glance.store.http.StoreLocation({}) loc.parse_uri(uri) self.assertEqual("http", loc.scheme) self.assertEqual("example.com", loc.netloc) self.assertEqual("/images/1", loc.path) self.assertEqual(uri, loc.get_uri()) uri = 'https://example.com:8080/images/container/1' loc.parse_uri(uri) self.assertEqual("https", loc.scheme) self.assertEqual("example.com:8080", loc.netloc) self.assertEqual("/images/container/1", loc.path) self.assertEqual(uri, loc.get_uri()) uri = 'https://user:password@example.com:8080/images/container/1' loc.parse_uri(uri) self.assertEqual("https", loc.scheme) self.assertEqual("example.com:8080", loc.netloc) self.assertEqual("user", loc.user) self.assertEqual("password", loc.password) self.assertEqual("/images/container/1", loc.path) self.assertEqual(uri, loc.get_uri()) uri = 'https://user:@example.com:8080/images/1' loc.parse_uri(uri) self.assertEqual("https", loc.scheme) self.assertEqual("example.com:8080", loc.netloc) self.assertEqual("user", loc.user) self.assertEqual("", loc.password) self.assertEqual("/images/1", loc.path) self.assertEqual(uri, loc.get_uri()) bad_uri = 'htt://' self.assertRaises(AssertionError, loc.parse_uri, bad_uri) bad_uri = 'http://' self.assertRaises(exception.BadStoreUri, loc.parse_uri, bad_uri) bad_uri = 'http://user@example.com:8080/images/1' self.assertRaises(exception.BadStoreUri, loc.parse_uri, bad_uri) def test_swift_store_location(self): """ Test the specific StoreLocation for the Swift store """ uri = 'swift://example.com/images/1' loc = glance.store.swift.StoreLocation({}) loc.parse_uri(uri) self.assertEqual("swift", loc.scheme) self.assertEqual("example.com", loc.auth_or_store_url) self.assertEqual("https://example.com", loc.swift_url) self.assertEqual("images", loc.container) self.assertEqual("1", loc.obj) self.assertIsNone(loc.user) self.assertEqual(uri, loc.get_uri()) uri = 'swift+https://user:pass@authurl.com/images/1' loc.parse_uri(uri) self.assertEqual("swift+https", loc.scheme) self.assertEqual("authurl.com", loc.auth_or_store_url) self.assertEqual("https://authurl.com", loc.swift_url) self.assertEqual("images", loc.container) self.assertEqual("1", loc.obj) self.assertEqual("user", loc.user) self.assertEqual("pass", loc.key) self.assertEqual(uri, loc.get_uri()) uri = 'swift+https://user:pass@authurl.com/v1/container/12345' loc.parse_uri(uri) self.assertEqual("swift+https", loc.scheme) self.assertEqual("authurl.com/v1", loc.auth_or_store_url) self.assertEqual("https://authurl.com/v1", loc.swift_url) self.assertEqual("container", loc.container) self.assertEqual("12345", loc.obj) self.assertEqual("user", loc.user) self.assertEqual("pass", loc.key) self.assertEqual(uri, loc.get_uri()) uri = ('swift+http://a%3Auser%40example.com:p%40ss@authurl.com/' 'v1/container/12345') loc.parse_uri(uri) self.assertEqual("swift+http", loc.scheme) self.assertEqual("authurl.com/v1", loc.auth_or_store_url) self.assertEqual("http://authurl.com/v1", loc.swift_url) self.assertEqual("container", loc.container) self.assertEqual("12345", loc.obj) self.assertEqual("a:user@example.com", loc.user) self.assertEqual("p@ss", loc.key) self.assertEqual(uri, loc.get_uri()) # multitenant puts store URL in the location (not auth) uri = ('swift+http://storeurl.com/v1/container/12345') loc.parse_uri(uri) self.assertEqual("swift+http", loc.scheme) self.assertEqual("storeurl.com/v1", loc.auth_or_store_url) self.assertEqual("http://storeurl.com/v1", loc.swift_url) self.assertEqual("container", loc.container) self.assertEqual("12345", loc.obj) self.assertIsNone(loc.user) self.assertIsNone(loc.key) self.assertEqual(uri, loc.get_uri()) bad_uri = 'swif://' self.assertRaises(AssertionError, loc.parse_uri, bad_uri) bad_uri = 'swift://' self.assertRaises(exception.BadStoreUri, loc.parse_uri, bad_uri) bad_uri = 'swift://user@example.com:8080/images/1' self.assertRaises(exception.BadStoreUri, loc.parse_uri, bad_uri) bad_uri = 'swift://user:pass@http://example.com:8080/images/1' self.assertRaises(exception.BadStoreUri, loc.parse_uri, bad_uri) def test_s3_store_location(self): """ Test the specific StoreLocation for the S3 store """ uri = 's3://example.com/images/1' loc = glance.store.s3.StoreLocation({}) loc.parse_uri(uri) self.assertEqual("s3", loc.scheme) self.assertEqual("example.com", loc.s3serviceurl) self.assertEqual("images", loc.bucket) self.assertEqual("1", loc.key) self.assertIsNone(loc.accesskey) self.assertEqual(uri, loc.get_uri()) uri = 's3+https://accesskey:pass@s3serviceurl.com/images/1' loc.parse_uri(uri) self.assertEqual("s3+https", loc.scheme) self.assertEqual("s3serviceurl.com", loc.s3serviceurl) self.assertEqual("images", loc.bucket) self.assertEqual("1", loc.key) self.assertEqual("accesskey", loc.accesskey) self.assertEqual("pass", loc.secretkey) self.assertEqual(uri, loc.get_uri()) uri = 's3+https://accesskey:pass@s3serviceurl.com/v1/bucket/12345' loc.parse_uri(uri) self.assertEqual("s3+https", loc.scheme) self.assertEqual("s3serviceurl.com/v1", loc.s3serviceurl) self.assertEqual("bucket", loc.bucket) self.assertEqual("12345", loc.key) self.assertEqual("accesskey", loc.accesskey) self.assertEqual("pass", loc.secretkey) self.assertEqual(uri, loc.get_uri()) uri = 's3://accesskey:pass/withslash@s3serviceurl.com/v1/bucket/12345' loc.parse_uri(uri) self.assertEqual("s3", loc.scheme) self.assertEqual("s3serviceurl.com/v1", loc.s3serviceurl) self.assertEqual("bucket", loc.bucket) self.assertEqual("12345", loc.key) self.assertEqual("accesskey", loc.accesskey) self.assertEqual("pass/withslash", loc.secretkey) self.assertEqual(uri, loc.get_uri()) bad_uri = 's://' self.assertRaises(AssertionError, loc.parse_uri, bad_uri) bad_uri = 's3://' self.assertRaises(exception.BadStoreUri, loc.parse_uri, bad_uri) bad_uri = 's3://accesskey@example.com:8080/images/1' self.assertRaises(exception.BadStoreUri, loc.parse_uri, bad_uri) bad_uri = 's3://user:pass@http://example.com:8080/images/1' self.assertRaises(exception.BadStoreUri, loc.parse_uri, bad_uri) def test_rbd_store_location(self): """ Test the specific StoreLocation for the RBD store """ uri = 'rbd://imagename' loc = glance.store.rbd.StoreLocation({}) loc.parse_uri(uri) self.assertEqual('imagename', loc.image) self.assertIsNone(loc.fsid) self.assertIsNone(loc.pool) self.assertIsNone(loc.snapshot) uri = u'rbd://imagename' loc = glance.store.rbd.StoreLocation({}) loc.parse_uri(uri) self.assertEqual('imagename', loc.image) self.assertIsNone(loc.fsid) self.assertIsNone(loc.pool) self.assertIsNone(loc.snapshot) uri = 'rbd://fsid/pool/image/snap' loc = glance.store.rbd.StoreLocation({}) loc.parse_uri(uri) self.assertEqual('image', loc.image) self.assertEqual('fsid', loc.fsid) self.assertEqual('pool', loc.pool) self.assertEqual('snap', loc.snapshot) uri = u'rbd://fsid/pool/image/snap' loc = glance.store.rbd.StoreLocation({}) loc.parse_uri(uri) self.assertEqual('image', loc.image) self.assertEqual('fsid', loc.fsid) self.assertEqual('pool', loc.pool) self.assertEqual('snap', loc.snapshot) uri = 'rbd://%2f/%2f/%2f/%2f' loc = glance.store.rbd.StoreLocation({}) loc.parse_uri(uri) self.assertEqual('/', loc.image) self.assertEqual('/', loc.fsid) self.assertEqual('/', loc.pool) self.assertEqual('/', loc.snapshot) uri = u'rbd://%2f/%2f/%2f/%2f' loc = glance.store.rbd.StoreLocation({}) loc.parse_uri(uri) self.assertEqual('/', loc.image) self.assertEqual('/', loc.fsid) self.assertEqual('/', loc.pool) self.assertEqual('/', loc.snapshot) bad_uri = 'rbd:/image' self.assertRaises(exception.BadStoreUri, loc.parse_uri, bad_uri) bad_uri = 'rbd://image/extra' self.assertRaises(exception.BadStoreUri, loc.parse_uri, bad_uri) bad_uri = 'rbd://image/' self.assertRaises(exception.BadStoreUri, loc.parse_uri, bad_uri) bad_uri = 'http://image' self.assertRaises(exception.BadStoreUri, loc.parse_uri, bad_uri) bad_uri = 'http://fsid/pool/image/snap' self.assertRaises(exception.BadStoreUri, loc.parse_uri, bad_uri) bad_uri = 'rbd://fsid/pool/image/' self.assertRaises(exception.BadStoreUri, loc.parse_uri, bad_uri) bad_uri = 'rbd://fsid/pool/image/snap/' self.assertRaises(exception.BadStoreUri, loc.parse_uri, bad_uri) bad_uri = 'http://///' self.assertRaises(exception.BadStoreUri, loc.parse_uri, bad_uri) bad_uri = 'rbd://' + unichr(300) self.assertRaises(exception.BadStoreUri, loc.parse_uri, bad_uri) def test_sheepdog_store_location(self): """ Test the specific StoreLocation for the Sheepdog store """ uri = 'sheepdog://244e75f1-9c69-4167-9db7-1aa7d1973f6c' loc = glance.store.sheepdog.StoreLocation({}) loc.parse_uri(uri) self.assertEqual('244e75f1-9c69-4167-9db7-1aa7d1973f6c', loc.image) bad_uri = 'sheepdog:/244e75f1-9c69-4167-9db7-1aa7d1973f6c' self.assertRaises(exception.BadStoreUri, loc.parse_uri, bad_uri) bad_uri = 'http://244e75f1-9c69-4167-9db7-1aa7d1973f6c' self.assertRaises(exception.BadStoreUri, loc.parse_uri, bad_uri) bad_uri = 'image; name' self.assertRaises(exception.BadStoreUri, loc.parse_uri, bad_uri) def test_vmware_store_location(self): """ Test the specific StoreLocation for the VMware store """ ds_url_prefix = glance.store.vmware_datastore.DS_URL_PREFIX image_dir = glance.store.vmware_datastore.DEFAULT_STORE_IMAGE_DIR uri = ('vsphere://127.0.0.1%s%s/29038321?dcPath=my-dc&dsName=my-ds' % (ds_url_prefix, image_dir)) loc = glance.store.vmware_datastore.StoreLocation({}) loc.parse_uri(uri) self.assertEqual("vsphere", loc.scheme) self.assertEqual("127.0.0.1", loc.server_host) self.assertEqual("%s%s/29038321" % (ds_url_prefix, image_dir), loc.path) self.assertEqual("dcPath=my-dc&dsName=my-ds", loc.query) self.assertEqual(uri, loc.get_uri()) bad_uri = 'vphere://' self.assertRaises(exception.BadStoreUri, loc.parse_uri, bad_uri) bad_uri = ('vspheer://127.0.0.1%s%s/29038321?dcPath=my-dc&dsName=my-ds' % (ds_url_prefix, image_dir)) self.assertRaises(exception.BadStoreUri, loc.parse_uri, bad_uri) bad_uri = ('http://127.0.0.1%s%s/29038321?dcPath=my-dc&dsName=my-ds' % (ds_url_prefix, image_dir)) self.assertRaises(exception.BadStoreUri, loc.parse_uri, bad_uri) bad_uri = ('vsphere:/127.0.0.1%s%s/29038321?dcPath=my-dc&dsName=my-ds' % (ds_url_prefix, image_dir)) self.assertRaises(exception.BadStoreUri, loc.parse_uri, bad_uri) bad_uri = ('vsphere://127.0.0.1%s%s/29038321?dcPath=my-dc&dsName=my-ds' % (ds_url_prefix, "/folder_not_in_configuration")) self.assertRaises(exception.BadStoreUri, loc.parse_uri, bad_uri) bad_uri = ('vsphere://127.0.0.1%s%s/29038321?dcPath=my-dc&dsName=my-ds' % ("/wrong_folder_path", image_dir)) self.assertRaises(exception.BadStoreUri, loc.parse_uri, bad_uri) def test_cinder_store_good_location(self): """ Test the specific StoreLocation for the Cinder store """ good_uri = 'cinder://12345678-9012-3455-6789-012345678901' loc = glance.store.cinder.StoreLocation({}) loc.parse_uri(good_uri) self.assertEqual('12345678-9012-3455-6789-012345678901', loc.volume_id) def test_cinder_store_bad_location(self): """ Test the specific StoreLocation for the Cinder store """ bad_uri = 'cinder://volume-id-is-a-uuid' loc = glance.store.cinder.StoreLocation({}) self.assertRaises(exception.BadStoreUri, loc.parse_uri, bad_uri) def test_get_store_from_scheme(self): """ Test that the backend returned by glance.store.get_backend_class is correct or raises an appropriate error. """ good_results = { 'swift': glance.store.swift.SingleTenantStore, 'swift+http': glance.store.swift.SingleTenantStore, 'swift+https': glance.store.swift.SingleTenantStore, 's3': glance.store.s3.Store, 's3+http': glance.store.s3.Store, 's3+https': glance.store.s3.Store, 'file': glance.store.filesystem.Store, 'filesystem': glance.store.filesystem.Store, 'http': glance.store.http.Store, 'https': glance.store.http.Store, 'rbd': glance.store.rbd.Store, 'sheepdog': glance.store.sheepdog.Store, 'cinder': glance.store.cinder.Store, 'vsphere': glance.store.vmware_datastore.Store} ctx = context.RequestContext() for scheme, store in good_results.items(): store_obj = glance.store.get_store_from_scheme(ctx, scheme) self.assertEqual(store_obj.__class__, store) bad_results = ['fil', 'swift+h', 'unknown'] for store in bad_results: self.assertRaises(exception.UnknownScheme, glance.store.get_store_from_scheme, ctx, store) def test_add_location_for_image_without_size(self): class FakeImageProxy(): size = None context = None store_api = mock.Mock() def fake_get_size_from_backend(context, uri): return 1 self.stubs.Set(glance.store, 'get_size_from_backend', fake_get_size_from_backend) with mock.patch('glance.store._check_image_location'): loc1 = {'url': 'file:///fake1.img.tar.gz', 'metadata': {}} loc2 = {'url': 'file:///fake2.img.tar.gz', 'metadata': {}} # Test for insert location image1 = FakeImageProxy() locations = glance.store.StoreLocations(image1, []) locations.insert(0, loc2) self.assertEqual(image1.size, 1) # Test for set_attr of _locations_proxy image2 = FakeImageProxy() locations = glance.store.StoreLocations(image2, [loc1]) locations[0] = loc2 self.assertTrue(loc2 in locations) self.assertEqual(image2.size, 1) glance-2014.1/glance/tests/unit/test_auth.py0000664000175400017540000011061512323736230022121 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation # Copyright 2013 IBM Corp. # 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 stubout import webob from glance.api import authorization from glance.common import auth from glance.common import exception import glance.domain from glance.openstack.common import jsonutils from glance.openstack.common import timeutils from glance.tests.unit import utils as unittest_utils from glance.tests import utils TENANT1 = '6838eb7b-6ded-434a-882c-b344c77fe8df' TENANT2 = '2c014f32-55eb-467d-8fcb-4bd706012f81' UUID1 = 'c80a1a6c-bd1f-41c5-90ee-81afedb1d58d' UUID2 = 'a85abd86-55b3-4d5b-b0b4-5d0a6e6042fc' class FakeResponse(object): """ Simple class that masks the inconsistency between webob.Response.status_int and httplib.Response.status """ def __init__(self, resp): self.resp = resp def __getitem__(self, key): return self.resp.headers.get(key) @property def status(self): return self.resp.status_int class V2Token(object): def __init__(self): self.tok = self.base_token def add_service_no_type(self): catalog = self.tok['access']['serviceCatalog'] service_type = {"name": "glance_no_type"} catalog.append(service_type) service = catalog[-1] service['endpoints'] = [self.base_endpoint] def add_service(self, s_type, region_list=[]): catalog = self.tok['access']['serviceCatalog'] service_type = {"type": s_type, "name": "glance"} catalog.append(service_type) service = catalog[-1] endpoint_list = [] if region_list == []: endpoint_list.append(self.base_endpoint) else: for region in region_list: endpoint = self.base_endpoint endpoint['region'] = region endpoint_list.append(endpoint) service['endpoints'] = endpoint_list @property def token(self): return self.tok @property def base_endpoint(self): return { "adminURL": "http://localhost:9292", "internalURL": "http://localhost:9292", "publicURL": "http://localhost:9292" } @property def base_token(self): return { "access": { "token": { "expires": "2010-11-23T16:40:53.321584", "id": "5c7f8799-2e54-43e4-851b-31f81871b6c", "tenant": {"id": "1", "name": "tenant-ok"} }, "serviceCatalog": [ ], "user": { "id": "2", "roles": [{ "tenantId": "1", "id": "1", "name": "Admin" }], "name": "joeadmin" } } } class TestKeystoneAuthPlugin(utils.BaseTestCase): """Test that the Keystone auth plugin works properly""" def setUp(self): super(TestKeystoneAuthPlugin, self).setUp() self.stubs = stubout.StubOutForTesting() self.addCleanup(self.stubs.UnsetAll) def test_get_plugin_from_strategy_keystone(self): strategy = auth.get_plugin_from_strategy('keystone') self.assertIsInstance(strategy, auth.KeystoneStrategy) self.assertTrue(strategy.configure_via_auth) def test_get_plugin_from_strategy_keystone_configure_via_auth_false(self): strategy = auth.get_plugin_from_strategy('keystone', configure_via_auth=False) self.assertIsInstance(strategy, auth.KeystoneStrategy) self.assertFalse(strategy.configure_via_auth) def test_required_creds(self): """ Test that plugin created without required credential pieces raises an exception """ bad_creds = [ {}, # missing everything { 'username': 'user1', 'strategy': 'keystone', 'password': 'pass' }, # missing auth_url { 'password': 'pass', 'strategy': 'keystone', 'auth_url': 'http://localhost/v1' }, # missing username { 'username': 'user1', 'strategy': 'keystone', 'auth_url': 'http://localhost/v1' }, # missing password { 'username': 'user1', 'password': 'pass', 'auth_url': 'http://localhost/v1' }, # missing strategy { 'username': 'user1', 'password': 'pass', 'strategy': 'keystone', 'auth_url': 'http://localhost/v2.0/' }, # v2.0: missing tenant { 'username': None, 'password': 'pass', 'auth_url': 'http://localhost/v2.0/' }, # None parameter { 'username': 'user1', 'password': 'pass', 'auth_url': 'http://localhost/v2.0/', 'tenant': None } # None tenant ] for creds in bad_creds: try: plugin = auth.KeystoneStrategy(creds) plugin.authenticate() self.fail("Failed to raise correct exception when supplying " "bad credentials: %r" % creds) except exception.MissingCredentialError: continue # Expected def test_invalid_auth_url_v1(self): """ Test that a 400 during authenticate raises exception.AuthBadRequest """ def fake_do_request(*args, **kwargs): resp = webob.Response() resp.status = 400 return FakeResponse(resp), "" self.stubs.Set(auth.KeystoneStrategy, '_do_request', fake_do_request) bad_creds = { 'username': 'user1', 'auth_url': 'http://localhost/badauthurl/', 'password': 'pass', 'strategy': 'keystone', 'region': 'RegionOne' } plugin = auth.KeystoneStrategy(bad_creds) self.assertRaises(exception.AuthBadRequest, plugin.authenticate) def test_invalid_auth_url_v2(self): """ Test that a 400 during authenticate raises exception.AuthBadRequest """ def fake_do_request(*args, **kwargs): resp = webob.Response() resp.status = 400 return FakeResponse(resp), "" self.stubs.Set(auth.KeystoneStrategy, '_do_request', fake_do_request) bad_creds = { 'username': 'user1', 'auth_url': 'http://localhost/badauthurl/v2.0/', 'password': 'pass', 'tenant': 'tenant1', 'strategy': 'keystone', 'region': 'RegionOne' } plugin = auth.KeystoneStrategy(bad_creds) self.assertRaises(exception.AuthBadRequest, plugin.authenticate) def test_v1_auth(self): """Test v1 auth code paths""" def fake_do_request(cls, url, method, headers=None, body=None): if url.find("2.0") != -1: self.fail("Invalid v1.0 token path (%s)" % url) headers = headers or {} resp = webob.Response() if (headers.get('X-Auth-User') != 'user1' or headers.get('X-Auth-Key') != 'pass'): resp.status = 401 else: resp.status = 200 resp.headers.update({"x-image-management-url": "example.com"}) return FakeResponse(resp), "" self.stubs.Set(auth.KeystoneStrategy, '_do_request', fake_do_request) unauthorized_creds = [ { 'username': 'wronguser', 'auth_url': 'http://localhost/badauthurl/', 'strategy': 'keystone', 'region': 'RegionOne', 'password': 'pass' }, # wrong username { 'username': 'user1', 'auth_url': 'http://localhost/badauthurl/', 'strategy': 'keystone', 'region': 'RegionOne', 'password': 'badpass' }, # bad password... ] for creds in unauthorized_creds: try: plugin = auth.KeystoneStrategy(creds) plugin.authenticate() self.fail("Failed to raise NotAuthenticated when supplying " "bad credentials: %r" % creds) except exception.NotAuthenticated: continue # Expected no_strategy_creds = { 'username': 'user1', 'auth_url': 'http://localhost/redirect/', 'password': 'pass', 'region': 'RegionOne' } try: plugin = auth.KeystoneStrategy(no_strategy_creds) plugin.authenticate() self.fail("Failed to raise MissingCredentialError when " "supplying no strategy: %r" % no_strategy_creds) except exception.MissingCredentialError: pass # Expected good_creds = [ { 'username': 'user1', 'auth_url': 'http://localhost/redirect/', 'password': 'pass', 'strategy': 'keystone', 'region': 'RegionOne' } ] for creds in good_creds: plugin = auth.KeystoneStrategy(creds) self.assertTrue(plugin.authenticate() is None) self.assertEqual(plugin.management_url, "example.com") # Assert it does not update management_url via auth response for creds in good_creds: plugin = auth.KeystoneStrategy(creds, configure_via_auth=False) self.assertTrue(plugin.authenticate() is None) self.assertTrue(plugin.management_url is None) def test_v2_auth(self): """Test v2 auth code paths""" mock_token = None def fake_do_request(cls, url, method, headers=None, body=None): if (not url.rstrip('/').endswith('v2.0/tokens') or url.count("2.0") != 1): self.fail("Invalid v2.0 token path (%s)" % url) creds = jsonutils.loads(body)['auth'] username = creds['passwordCredentials']['username'] password = creds['passwordCredentials']['password'] tenant = creds['tenantName'] resp = webob.Response() if (username != 'user1' or password != 'pass' or tenant != 'tenant-ok'): resp.status = 401 else: resp.status = 200 body = mock_token.token return FakeResponse(resp), jsonutils.dumps(body) mock_token = V2Token() mock_token.add_service('image', ['RegionOne']) self.stubs.Set(auth.KeystoneStrategy, '_do_request', fake_do_request) unauthorized_creds = [ { 'username': 'wronguser', 'auth_url': 'http://localhost/v2.0', 'password': 'pass', 'tenant': 'tenant-ok', 'strategy': 'keystone', 'region': 'RegionOne' }, # wrong username { 'username': 'user1', 'auth_url': 'http://localhost/v2.0', 'password': 'badpass', 'tenant': 'tenant-ok', 'strategy': 'keystone', 'region': 'RegionOne' }, # bad password... { 'username': 'user1', 'auth_url': 'http://localhost/v2.0', 'password': 'pass', 'tenant': 'carterhayes', 'strategy': 'keystone', 'region': 'RegionOne' }, # bad tenant... ] for creds in unauthorized_creds: try: plugin = auth.KeystoneStrategy(creds) plugin.authenticate() self.fail("Failed to raise NotAuthenticated when supplying " "bad credentials: %r" % creds) except exception.NotAuthenticated: continue # Expected no_region_creds = { 'username': 'user1', 'tenant': 'tenant-ok', 'auth_url': 'http://localhost/redirect/v2.0/', 'password': 'pass', 'strategy': 'keystone' } plugin = auth.KeystoneStrategy(no_region_creds) self.assertTrue(plugin.authenticate() is None) self.assertEqual(plugin.management_url, 'http://localhost:9292') # Add another image service, with a different region mock_token.add_service('image', ['RegionTwo']) try: plugin = auth.KeystoneStrategy(no_region_creds) plugin.authenticate() self.fail("Failed to raise RegionAmbiguity when no region present " "and multiple regions exist: %r" % no_region_creds) except exception.RegionAmbiguity: pass # Expected wrong_region_creds = { 'username': 'user1', 'tenant': 'tenant-ok', 'auth_url': 'http://localhost/redirect/v2.0/', 'password': 'pass', 'strategy': 'keystone', 'region': 'NonExistentRegion' } try: plugin = auth.KeystoneStrategy(wrong_region_creds) plugin.authenticate() self.fail("Failed to raise NoServiceEndpoint when supplying " "wrong region: %r" % wrong_region_creds) except exception.NoServiceEndpoint: pass # Expected no_strategy_creds = { 'username': 'user1', 'tenant': 'tenant-ok', 'auth_url': 'http://localhost/redirect/v2.0/', 'password': 'pass', 'region': 'RegionOne' } try: plugin = auth.KeystoneStrategy(no_strategy_creds) plugin.authenticate() self.fail("Failed to raise MissingCredentialError when " "supplying no strategy: %r" % no_strategy_creds) except exception.MissingCredentialError: pass # Expected bad_strategy_creds = { 'username': 'user1', 'tenant': 'tenant-ok', 'auth_url': 'http://localhost/redirect/v2.0/', 'password': 'pass', 'region': 'RegionOne', 'strategy': 'keypebble' } try: plugin = auth.KeystoneStrategy(bad_strategy_creds) plugin.authenticate() self.fail("Failed to raise BadAuthStrategy when supplying " "bad auth strategy: %r" % bad_strategy_creds) except exception.BadAuthStrategy: pass # Expected mock_token = V2Token() mock_token.add_service('image', ['RegionOne', 'RegionTwo']) good_creds = [ { 'username': 'user1', 'auth_url': 'http://localhost/v2.0/', 'password': 'pass', 'tenant': 'tenant-ok', 'strategy': 'keystone', 'region': 'RegionOne' }, # auth_url with trailing '/' { 'username': 'user1', 'auth_url': 'http://localhost/v2.0', 'password': 'pass', 'tenant': 'tenant-ok', 'strategy': 'keystone', 'region': 'RegionOne' }, # auth_url without trailing '/' { 'username': 'user1', 'auth_url': 'http://localhost/v2.0', 'password': 'pass', 'tenant': 'tenant-ok', 'strategy': 'keystone', 'region': 'RegionTwo' } # Second region ] for creds in good_creds: plugin = auth.KeystoneStrategy(creds) self.assertTrue(plugin.authenticate() is None) self.assertEqual(plugin.management_url, 'http://localhost:9292') ambiguous_region_creds = { 'username': 'user1', 'auth_url': 'http://localhost/v2.0/', 'password': 'pass', 'tenant': 'tenant-ok', 'strategy': 'keystone', 'region': 'RegionOne' } mock_token = V2Token() # Add two identical services mock_token.add_service('image', ['RegionOne']) mock_token.add_service('image', ['RegionOne']) try: plugin = auth.KeystoneStrategy(ambiguous_region_creds) plugin.authenticate() self.fail("Failed to raise RegionAmbiguity when " "non-unique regions exist: %r" % ambiguous_region_creds) except exception.RegionAmbiguity: pass mock_token = V2Token() mock_token.add_service('bad-image', ['RegionOne']) good_creds = { 'username': 'user1', 'auth_url': 'http://localhost/v2.0/', 'password': 'pass', 'tenant': 'tenant-ok', 'strategy': 'keystone', 'region': 'RegionOne' } try: plugin = auth.KeystoneStrategy(good_creds) plugin.authenticate() self.fail("Failed to raise NoServiceEndpoint when bad service " "type encountered") except exception.NoServiceEndpoint: pass mock_token = V2Token() mock_token.add_service_no_type() try: plugin = auth.KeystoneStrategy(good_creds) plugin.authenticate() self.fail("Failed to raise NoServiceEndpoint when bad service " "type encountered") except exception.NoServiceEndpoint: pass try: plugin = auth.KeystoneStrategy(good_creds, configure_via_auth=False) plugin.authenticate() except exception.NoServiceEndpoint: self.fail("NoServiceEndpoint was raised when authenticate " "should not check for endpoint.") class TestEndpoints(utils.BaseTestCase): def setUp(self): super(TestEndpoints, self).setUp() self.service_catalog = [ { 'endpoint_links': [], 'endpoints': [ { 'adminURL': 'http://localhost:8080/', 'region': 'RegionOne', 'internalURL': 'http://internalURL/', 'publicURL': 'http://publicURL/', }, ], 'type': 'object-store', 'name': 'Object Storage Service', } ] def test_get_endpoint_with_custom_server_type(self): endpoint = auth.get_endpoint(self.service_catalog, service_type='object-store') self.assertEqual('http://publicURL/', endpoint) def test_get_endpoint_with_custom_endpoint_type(self): endpoint = auth.get_endpoint(self.service_catalog, service_type='object-store', endpoint_type='internalURL') self.assertEqual('http://internalURL/', endpoint) def test_get_endpoint_raises_with_invalid_service_type(self): self.assertRaises(exception.NoServiceEndpoint, auth.get_endpoint, self.service_catalog, service_type='foo') def test_get_endpoint_raises_with_invalid_endpoint_type(self): self.assertRaises(exception.NoServiceEndpoint, auth.get_endpoint, self.service_catalog, service_type='object-store', endpoint_type='foo') def test_get_endpoint_raises_with_invalid_endpoint_region(self): self.assertRaises(exception.NoServiceEndpoint, auth.get_endpoint, self.service_catalog, service_type='object-store', endpoint_region='foo', endpoint_type='internalURL') class TestImageMutability(utils.BaseTestCase): def setUp(self): super(TestImageMutability, self).setUp() self.image_factory = glance.domain.ImageFactory() def _is_mutable(self, tenant, owner, is_admin=False): context = glance.context.RequestContext(tenant=tenant, is_admin=is_admin) image = self.image_factory.new_image(owner=owner) return authorization.is_image_mutable(context, image) def test_admin_everything_mutable(self): self.assertTrue(self._is_mutable(None, None, is_admin=True)) self.assertTrue(self._is_mutable(None, TENANT1, is_admin=True)) self.assertTrue(self._is_mutable(TENANT1, None, is_admin=True)) self.assertTrue(self._is_mutable(TENANT1, TENANT1, is_admin=True)) self.assertTrue(self._is_mutable(TENANT1, TENANT2, is_admin=True)) def test_no_tenant_nothing_mutable(self): self.assertFalse(self._is_mutable(None, None)) self.assertFalse(self._is_mutable(None, TENANT1)) def test_regular_user(self): self.assertFalse(self._is_mutable(TENANT1, None)) self.assertFalse(self._is_mutable(TENANT1, TENANT2)) self.assertTrue(self._is_mutable(TENANT1, TENANT1)) class TestImmutableImage(utils.BaseTestCase): def setUp(self): super(TestImmutableImage, self).setUp() image_factory = glance.domain.ImageFactory() self.context = glance.context.RequestContext(tenant=TENANT1) image = image_factory.new_image( image_id=UUID1, name='Marvin', owner=TENANT1, disk_format='raw', container_format='bare', extra_properties={'foo': 'bar'}, tags=['ping', 'pong'], ) self.image = authorization.ImmutableImageProxy(image, self.context) def _test_change(self, attr, value): self.assertRaises(exception.Forbidden, setattr, self.image, attr, value) self.assertRaises(exception.Forbidden, delattr, self.image, attr) def test_change_id(self): self._test_change('image_id', UUID2) def test_change_name(self): self._test_change('name', 'Freddie') def test_change_owner(self): self._test_change('owner', TENANT2) def test_change_min_disk(self): self._test_change('min_disk', 100) def test_change_min_ram(self): self._test_change('min_ram', 1024) def test_change_disk_format(self): self._test_change('disk_format', 'vhd') def test_change_container_format(self): self._test_change('container_format', 'ova') def test_change_visibility(self): self._test_change('visibility', 'public') def test_change_status(self): self._test_change('status', 'active') def test_change_created_at(self): self._test_change('created_at', timeutils.utcnow()) def test_change_updated_at(self): self._test_change('updated_at', timeutils.utcnow()) def test_change_locations(self): self._test_change('locations', ['http://a/b/c']) self.assertRaises(exception.Forbidden, self.image.locations.append, 'http://a/b/c') self.assertRaises(exception.Forbidden, self.image.locations.extend, ['http://a/b/c']) self.assertRaises(exception.Forbidden, self.image.locations.insert, 'foo') self.assertRaises(exception.Forbidden, self.image.locations.pop) self.assertRaises(exception.Forbidden, self.image.locations.remove, 'foo') self.assertRaises(exception.Forbidden, self.image.locations.reverse) self.assertRaises(exception.Forbidden, self.image.locations.sort) self.assertRaises(exception.Forbidden, self.image.locations.__delitem__, 0) self.assertRaises(exception.Forbidden, self.image.locations.__delslice__, 0, 2) self.assertRaises(exception.Forbidden, self.image.locations.__setitem__, 0, 'foo') self.assertRaises(exception.Forbidden, self.image.locations.__setslice__, 0, 2, ['foo', 'bar']) self.assertRaises(exception.Forbidden, self.image.locations.__iadd__, 'foo') self.assertRaises(exception.Forbidden, self.image.locations.__imul__, 2) def test_change_size(self): self._test_change('size', 32) def test_change_tags(self): self.assertRaises(exception.Forbidden, delattr, self.image, 'tags') self.assertRaises(exception.Forbidden, setattr, self.image, 'tags', ['king', 'kong']) self.assertRaises(exception.Forbidden, self.image.tags.pop) self.assertRaises(exception.Forbidden, self.image.tags.clear) self.assertRaises(exception.Forbidden, self.image.tags.add, 'king') self.assertRaises(exception.Forbidden, self.image.tags.remove, 'ping') self.assertRaises(exception.Forbidden, self.image.tags.update, set(['king', 'kong'])) self.assertRaises(exception.Forbidden, self.image.tags.intersection_update, set([])) self.assertRaises(exception.Forbidden, self.image.tags.difference_update, set([])) self.assertRaises(exception.Forbidden, self.image.tags.symmetric_difference_update, set([])) def test_change_properties(self): self.assertRaises(exception.Forbidden, delattr, self.image, 'extra_properties') self.assertRaises(exception.Forbidden, setattr, self.image, 'extra_properties', {}) self.assertRaises(exception.Forbidden, self.image.extra_properties.__delitem__, 'foo') self.assertRaises(exception.Forbidden, self.image.extra_properties.__setitem__, 'foo', 'b') self.assertRaises(exception.Forbidden, self.image.extra_properties.__setitem__, 'z', 'j') self.assertRaises(exception.Forbidden, self.image.extra_properties.pop) self.assertRaises(exception.Forbidden, self.image.extra_properties.popitem) self.assertRaises(exception.Forbidden, self.image.extra_properties.setdefault, 'p', 'j') self.assertRaises(exception.Forbidden, self.image.extra_properties.update, {}) def test_delete(self): self.assertRaises(exception.Forbidden, self.image.delete) def test_set_data(self): self.assertRaises(exception.Forbidden, self.image.set_data, 'blah', 4) def test_get_data(self): class FakeImage(object): def get_data(self): return 'tiddlywinks' image = glance.api.authorization.ImmutableImageProxy( FakeImage(), self.context) self.assertEqual(image.get_data(), 'tiddlywinks') class TestImageFactoryProxy(utils.BaseTestCase): def setUp(self): super(TestImageFactoryProxy, self).setUp() factory = glance.domain.ImageFactory() self.context = glance.context.RequestContext(tenant=TENANT1) self.image_factory = authorization.ImageFactoryProxy(factory, self.context) def test_default_owner_is_set(self): image = self.image_factory.new_image() self.assertEqual(image.owner, TENANT1) def test_wrong_owner_cannot_be_set(self): self.assertRaises(exception.Forbidden, self.image_factory.new_image, owner=TENANT2) def test_cannot_set_owner_to_none(self): self.assertRaises(exception.Forbidden, self.image_factory.new_image, owner=None) def test_admin_can_set_any_owner(self): self.context.is_admin = True image = self.image_factory.new_image(owner=TENANT2) self.assertEqual(image.owner, TENANT2) def test_admin_can_set_owner_to_none(self): self.context.is_admin = True image = self.image_factory.new_image(owner=None) self.assertIsNone(image.owner) def test_admin_still_gets_default_tenant(self): self.context.is_admin = True image = self.image_factory.new_image() self.assertEqual(image.owner, TENANT1) class TestImageRepoProxy(utils.BaseTestCase): class ImageRepoStub(object): def __init__(self, fixtures): self.fixtures = fixtures def get(self, image_id): for f in self.fixtures: if f.image_id == image_id: return f else: raise ValueError(image_id) def list(self, *args, **kwargs): return self.fixtures def setUp(self): super(TestImageRepoProxy, self).setUp() image_factory = glance.domain.ImageFactory() self.fixtures = [ image_factory.new_image(owner=TENANT1), image_factory.new_image(owner=TENANT2, visibility='public'), image_factory.new_image(owner=TENANT2), ] self.context = glance.context.RequestContext(tenant=TENANT1) image_repo = self.ImageRepoStub(self.fixtures) self.image_repo = authorization.ImageRepoProxy(image_repo, self.context) def test_get_mutable_image(self): image = self.image_repo.get(self.fixtures[0].image_id) self.assertEqual(image.image_id, self.fixtures[0].image_id) def test_get_immutable_image(self): image = self.image_repo.get(self.fixtures[1].image_id) self.assertRaises(exception.Forbidden, setattr, image, 'name', 'Vince') def test_list(self): images = self.image_repo.list() self.assertEqual(images[0].image_id, self.fixtures[0].image_id) self.assertRaises(exception.Forbidden, setattr, images[1], 'name', 'Wally') self.assertRaises(exception.Forbidden, setattr, images[2], 'name', 'Calvin') class TestImmutableTask(utils.BaseTestCase): def setUp(self): super(TestImmutableTask, self).setUp() task_factory = glance.domain.TaskFactory() self.context = glance.context.RequestContext(tenant=TENANT2) task_type = 'import' owner = TENANT2 task = task_factory.new_task(task_type, owner) self.task = authorization.ImmutableTaskProxy(task) def _test_change(self, attr, value): self.assertRaises( exception.Forbidden, setattr, self.task, attr, value ) self.assertRaises( exception.Forbidden, delattr, self.task, attr ) def test_change_id(self): self._test_change('task_id', UUID2) def test_change_type(self): self._test_change('type', 'fake') def test_change_status(self): self._test_change('status', 'success') def test_change_owner(self): self._test_change('owner', 'fake') def test_change_expires_at(self): self._test_change('expires_at', 'fake') def test_change_created_at(self): self._test_change('created_at', 'fake') def test_change_updated_at(self): self._test_change('updated_at', 'fake') def test_begin_processing(self): self.assertRaises( exception.Forbidden, self.task.begin_processing ) def test_succeed(self): self.assertRaises( exception.Forbidden, self.task.succeed, 'result' ) def test_fail(self): self.assertRaises( exception.Forbidden, self.task.fail, 'message' ) class TestTaskFactoryProxy(utils.BaseTestCase): def setUp(self): super(TestTaskFactoryProxy, self).setUp() factory = glance.domain.TaskFactory() self.context = glance.context.RequestContext(tenant=TENANT1) self.context_owner_is_none = glance.context.RequestContext() self.task_factory = authorization.TaskFactoryProxy( factory, self.context ) self.task_type = 'import' self.task_input = '{"loc": "fake"}' self.owner = 'foo' self.request1 = unittest_utils.get_fake_request(tenant=TENANT1) self.request2 = unittest_utils.get_fake_request(tenant=TENANT2) def test_task_create_default_owner(self): owner = self.request1.context.owner task = self.task_factory.new_task(task_type=self.task_type, owner=owner) self.assertEqual(task.owner, TENANT1) def test_task_create_wrong_owner(self): self.assertRaises(exception.Forbidden, self.task_factory.new_task, task_type=self.task_type, task_input=self.task_input, owner=self.owner) def test_task_create_owner_as_None(self): self.assertRaises(exception.Forbidden, self.task_factory.new_task, task_type=self.task_type, task_input=self.task_input, owner=None) def test_task_create_admin_context_owner_as_None(self): self.context.is_admin = True self.assertRaises(exception.Forbidden, self.task_factory.new_task, task_type=self.task_type, task_input=self.task_input, owner=None) class TestTaskRepoProxy(utils.BaseTestCase): class TaskRepoStub(object): def __init__(self, fixtures): self.fixtures = fixtures def get_task_and_details(self, task_id): for f in self.fixtures: if f.task_id == task_id: return f, None else: raise ValueError(task_id) def list_tasks(self, *args, **kwargs): return self.fixtures def setUp(self): super(TestTaskRepoProxy, self).setUp() task_factory = glance.domain.TaskFactory() task_type = 'import' owner = None self.fixtures = [ task_factory.new_task(task_type, owner), task_factory.new_task(task_type, owner), task_factory.new_task(task_type, owner), ] self.context = glance.context.RequestContext(tenant=TENANT1) task_repo = self.TaskRepoStub(self.fixtures) self.task_repo = authorization.TaskRepoProxy( task_repo, self.context ) def test_get_mutable_task(self): task, _ = self.task_repo.get_task_and_details(self.fixtures[0].task_id) self.assertEqual(task.task_id, self.fixtures[0].task_id) def test_get_immutable_task(self): task_id = self.fixtures[1].task_id task, task_details = self.task_repo.get_task_and_details(task_id) self.assertRaises(exception.Forbidden, setattr, task_details, 'input', 'foo') def test_list(self): tasks = self.task_repo.list_tasks() self.assertEqual(tasks[0].task_id, self.fixtures[0].task_id) self.assertRaises(exception.Forbidden, setattr, tasks[1], 'owner', 'foo') self.assertRaises(exception.Forbidden, setattr, tasks[2], 'owner', 'foo') glance-2014.1/glance/tests/unit/test_cache_middleware.py0000664000175400017540000003511712323736226024430 0ustar jenkinsjenkins00000000000000# Copyright 2012 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import testtools import webob import glance.api.middleware.cache from glance.common import exception from glance import context import glance.db.sqlalchemy.api as db import glance.registry.client.v1.api as registry from glance.tests.unit import base from glance.tests.unit import utils as unit_test_utils class TestCacheMiddlewareURLMatching(testtools.TestCase): def test_v1_no_match_detail(self): req = webob.Request.blank('/v1/images/detail') out = glance.api.middleware.cache.CacheFilter._match_request(req) self.assertTrue(out is None) def test_v1_no_match_detail_with_query_params(self): req = webob.Request.blank('/v1/images/detail?limit=10') out = glance.api.middleware.cache.CacheFilter._match_request(req) self.assertTrue(out is None) def test_v1_match_id_with_query_param(self): req = webob.Request.blank('/v1/images/asdf?ping=pong') out = glance.api.middleware.cache.CacheFilter._match_request(req) self.assertEqual(out, ('v1', 'GET', 'asdf')) def test_v2_match_id(self): req = webob.Request.blank('/v2/images/asdf/file') out = glance.api.middleware.cache.CacheFilter._match_request(req) self.assertEqual(out, ('v2', 'GET', 'asdf')) def test_v2_no_match_bad_path(self): req = webob.Request.blank('/v2/images/asdf') out = glance.api.middleware.cache.CacheFilter._match_request(req) self.assertTrue(out is None) def test_no_match_unknown_version(self): req = webob.Request.blank('/v3/images/asdf') out = glance.api.middleware.cache.CacheFilter._match_request(req) self.assertTrue(out is None) class TestCacheMiddlewareRequestStashCacheInfo(testtools.TestCase): def setUp(self): super(TestCacheMiddlewareRequestStashCacheInfo, self).setUp() self.request = webob.Request.blank('') self.middleware = glance.api.middleware.cache.CacheFilter def test_stash_cache_request_info(self): self.middleware._stash_request_info(self.request, 'asdf', 'GET') self.assertEqual(self.request.environ['api.cache.image_id'], 'asdf') self.assertEqual(self.request.environ['api.cache.method'], 'GET') def test_fetch_cache_request_info(self): self.request.environ['api.cache.image_id'] = 'asdf' self.request.environ['api.cache.method'] = 'GET' (image_id, method) = self.middleware._fetch_request_info(self.request) self.assertEqual('asdf', image_id) self.assertEqual('GET', method) def test_fetch_cache_request_info_unset(self): out = self.middleware._fetch_request_info(self.request) self.assertIsNone(out) class ChecksumTestCacheFilter(glance.api.middleware.cache.CacheFilter): def __init__(self): class DummyCache(object): def get_caching_iter(self, image_id, image_checksum, app_iter): self.image_checksum = image_checksum self.cache = DummyCache() self.policy = unit_test_utils.FakePolicyEnforcer() class TestCacheMiddlewareChecksumVerification(base.IsolatedUnitTest): def setUp(self): super(TestCacheMiddlewareChecksumVerification, self).setUp() self.context = context.RequestContext(is_admin=True) self.request = webob.Request.blank('') self.request.context = self.context def test_checksum_v1_header(self): cache_filter = ChecksumTestCacheFilter() headers = {"x-image-meta-checksum": "1234567890"} resp = webob.Response(request=self.request, headers=headers) cache_filter._process_GET_response(resp, None) self.assertEqual("1234567890", cache_filter.cache.image_checksum) def test_checksum_v2_header(self): cache_filter = ChecksumTestCacheFilter() headers = { "x-image-meta-checksum": "1234567890", "Content-MD5": "abcdefghi" } resp = webob.Response(request=self.request, headers=headers) cache_filter._process_GET_response(resp, None) self.assertEqual("abcdefghi", cache_filter.cache.image_checksum) def test_checksum_missing_header(self): cache_filter = ChecksumTestCacheFilter() resp = webob.Response(request=self.request) cache_filter._process_GET_response(resp, None) self.assertIsNone(cache_filter.cache.image_checksum) class FakeImageSerializer(object): def show(self, response, raw_response): return True class ProcessRequestTestCacheFilter(glance.api.middleware.cache.CacheFilter): def __init__(self): self.serializer = FakeImageSerializer() class DummyCache(object): def __init__(self): self.deleted_images = [] def is_cached(self, image_id): return True def get_caching_iter(self, image_id, image_checksum, app_iter): pass def delete_cached_image(self, image_id): self.deleted_images.append(image_id) def get_image_size(self, image_id): pass self.cache = DummyCache() self.policy = unit_test_utils.FakePolicyEnforcer() class TestCacheMiddlewareProcessRequest(base.IsolatedUnitTest): def test_v1_deleted_image_fetch(self): """ Test for determining that when an admin tries to download a deleted image it returns 404 Not Found error. """ def fake_get_image_metadata(context, image_id): return {'deleted': True} def dummy_img_iterator(): for i in range(3): yield i image_id = 'test1' request = webob.Request.blank('/v1/images/%s' % image_id) request.context = context.RequestContext() cache_filter = ProcessRequestTestCacheFilter() self.stubs.Set(registry, 'get_image_metadata', fake_get_image_metadata) self.assertRaises(exception.NotFound, cache_filter._process_v1_request, request, image_id, dummy_img_iterator) def test_process_v1_request_for_deleted_but_cached_image(self): """ Test for determining image is deleted from cache when it is not found in Glance Registry. """ def fake_process_v1_request(request, image_id, image_iterator): raise exception.NotFound() image_id = 'test1' request = webob.Request.blank('/v1/images/%s' % image_id) request.context = context.RequestContext() cache_filter = ProcessRequestTestCacheFilter() self.stubs.Set(cache_filter, '_process_v1_request', fake_process_v1_request) cache_filter.process_request(request) self.assertTrue(image_id in cache_filter.cache.deleted_images) def test_v1_process_request_image_fetch(self): def fake_get_image_metadata(context, image_id): return {'is_public': True, 'deleted': False, 'size': '20'} def dummy_img_iterator(): for i in range(3): yield i image_id = 'test1' request = webob.Request.blank('/v1/images/%s' % image_id) request.context = context.RequestContext() cache_filter = ProcessRequestTestCacheFilter() self.stubs.Set(registry, 'get_image_metadata', fake_get_image_metadata) actual = cache_filter._process_v1_request( request, image_id, dummy_img_iterator) self.assertTrue(actual) def test_v1_remove_location_image_fetch(self): class CheckNoLocationDataSerializer(object): def show(self, response, raw_response): return 'location_data' in raw_response['image_meta'] def fake_get_image_metadata(context, image_id): return {'location_data': {'url': "file:///some/path", 'metadata': {}}, 'is_public': True, 'deleted': False, 'size': '20'} def dummy_img_iterator(): for i in range(3): yield i image_id = 'test1' request = webob.Request.blank('/v1/images/%s' % image_id) request.context = context.RequestContext() cache_filter = ProcessRequestTestCacheFilter() cache_filter.serializer = CheckNoLocationDataSerializer() self.stubs.Set(registry, 'get_image_metadata', fake_get_image_metadata) actual = cache_filter._process_v1_request( request, image_id, dummy_img_iterator) self.assertFalse(actual) def test_verify_metadata_deleted_image(self): """ Test verify_metadata raises exception.NotFound for a deleted image """ image_meta = {'is_public': True, 'deleted': True} cache_filter = ProcessRequestTestCacheFilter() self.assertRaises(exception.NotFound, cache_filter._verify_metadata, image_meta) def test_verify_metadata_zero_size(self): """ Test verify_metadata updates metadata with cached image size for images with 0 size """ image_size = 1 def fake_get_image_size(image_id): return image_size image_id = 'test1' image_meta = {'size': 0, 'deleted': False, 'id': image_id} cache_filter = ProcessRequestTestCacheFilter() self.stubs.Set(cache_filter.cache, 'get_image_size', fake_get_image_size) cache_filter._verify_metadata(image_meta) self.assertTrue(image_meta['size'] == image_size) def test_v2_process_request_response_headers(self): def dummy_img_iterator(): for i in range(3): yield i def fake_image_get(self, image_id): return { 'id': 'test1', 'name': 'fake_image', 'status': 'active', 'created_at': '', 'min_disk': '10G', 'min_ram': '1024M', 'protected': False, 'locations': '', 'checksum': 'c352f4e7121c6eae958bc1570324f17e', 'owner': '', 'disk_format': 'raw', 'container_format': 'bare', 'size': '123456789', 'virtual_size': '123456789', 'is_public': 'public', 'deleted': False, 'updated_at': '', 'properties': {}, } def fake_image_tag_get_all(context, image_id, session=None): return None image_id = 'test1' request = webob.Request.blank('/v2/images/test1/file') request.context = context.RequestContext() self.stubs.Set(db, 'image_get', fake_image_get) self.stubs.Set(db, 'image_tag_get_all', fake_image_tag_get_all) cache_filter = ProcessRequestTestCacheFilter() response = cache_filter._process_v2_request( request, image_id, dummy_img_iterator) self.assertEqual(response.headers['Content-Type'], 'application/octet-stream') self.assertEqual(response.headers['Content-MD5'], 'c352f4e7121c6eae958bc1570324f17e') self.assertEqual(response.headers['Content-Length'], '123456789') def test_process_request_without_download_image_policy(self): """ Test for cache middleware skip processing when request context has not 'download_image' role. """ image_id = 'test1' request = webob.Request.blank('/v1/images/%s' % image_id) request.context = context.RequestContext() cache_filter = ProcessRequestTestCacheFilter() rules = {'download_image': '!'} self.set_policy_rules(rules) cache_filter.policy = glance.api.policy.Enforcer() self.assertIsNone(cache_filter.process_request(request)) class TestCacheMiddlewareProcessResponse(base.IsolatedUnitTest): def test_process_v1_DELETE_response(self): image_id = 'test1' request = webob.Request.blank('/v1/images/%s' % image_id) request.context = context.RequestContext() cache_filter = ProcessRequestTestCacheFilter() headers = {"x-image-meta-deleted": True} resp = webob.Response(request=request, headers=headers) actual = cache_filter._process_DELETE_response(resp, image_id) self.assertEqual(actual, resp) def test_get_status_code(self): headers = {"x-image-meta-deleted": True} resp = webob.Response(headers=headers) cache_filter = ProcessRequestTestCacheFilter() actual = cache_filter.get_status_code(resp) self.assertEqual(200, actual) def test_process_response(self): def fake_fetch_request_info(*args, **kwargs): return ('test1', 'GET') cache_filter = ProcessRequestTestCacheFilter() cache_filter._fetch_request_info = fake_fetch_request_info image_id = 'test1' request = webob.Request.blank('/v1/images/%s' % image_id) request.context = context.RequestContext() headers = {"x-image-meta-deleted": True} resp = webob.Response(request=request, headers=headers) actual = cache_filter.process_response(resp) self.assertEqual(actual, resp) def test_process_response_without_download_image_policy(self): """ Test for cache middleware raise webob.exc.HTTPForbidden directly when request context has not 'download_image' role. """ def fake_fetch_request_info(*args, **kwargs): return ('test1', 'GET') cache_filter = ProcessRequestTestCacheFilter() cache_filter._fetch_request_info = fake_fetch_request_info rules = {'download_image': '!'} self.set_policy_rules(rules) cache_filter.policy = glance.api.policy.Enforcer() image_id = 'test1' request = webob.Request.blank('/v1/images/%s' % image_id) request.context = context.RequestContext() resp = webob.Response(request=request) self.assertRaises(webob.exc.HTTPForbidden, cache_filter.process_response, resp) self.assertEqual([''], resp.app_iter) glance-2014.1/glance/tests/unit/test_store_base.py0000664000175400017540000000425012323736226023310 0ustar jenkinsjenkins00000000000000# Copyright 2011-2013 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from glance.common import exception from glance import store from glance.store import base as store_base from glance.tests.unit import base as test_base class FakeUnconfigurableStoreDriver(store_base.Store): def configure(self): raise exception.BadStoreConfiguration("Unconfigurable store driver.") class TestStoreBase(test_base.StoreClearingUnitTest): def setUp(self): self.config(default_store='file') super(TestStoreBase, self).setUp() def test_exception_to_unicode(self): class FakeException(Exception): def __str__(self): raise UnicodeError() exc = Exception('error message') ret = store_base._exception_to_unicode(exc) self.assertIsInstance(ret, unicode) self.assertEqual(ret, 'error message') exc = Exception('\xa5 error message') ret = store_base._exception_to_unicode(exc) self.assertIsInstance(ret, unicode) self.assertEqual(ret, ' error message') exc = FakeException('\xa5 error message') ret = store_base._exception_to_unicode(exc) self.assertIsInstance(ret, unicode) self.assertEqual(ret, _("Caught '%(exception)s' exception.") % {'exception': 'FakeException'}) def test_create_store_exclude_unconfigurable_drivers(self): self.config(known_stores=[ "glance.tests.unit.test_store_base.FakeUnconfigurableStoreDriver", "glance.store.filesystem.Store"]) count = store.create_stores() self.assertEqual(9, count) glance-2014.1/glance/tests/unit/test_s3_store.py0000664000175400017540000003457612323736226022741 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """Tests the S3 backend store""" import hashlib import uuid import boto.s3.connection import six import stubout from glance.common import exception from glance.openstack.common import units from glance.store.location import get_location_from_uri import glance.store.s3 from glance.store.s3 import get_s3_location from glance.store.s3 import Store from glance.store import UnsupportedBackend from glance.tests.unit import base FAKE_UUID = str(uuid.uuid4()) FIVE_KB = 5 * units.Ki S3_CONF = {'verbose': True, 'debug': True, 'default_store': 's3', 's3_store_access_key': 'user', 's3_store_secret_key': 'key', 's3_store_host': 'localhost:8080', 's3_store_bucket': 'glance', 'known_stores': ['glance.store.s3.Store']} # We stub out as little as possible to ensure that the code paths # between glance.store.s3 and boto.s3.connection are tested # thoroughly def stub_out_s3(stubs): class FakeKey: """ Acts like a ``boto.s3.key.Key`` """ def __init__(self, bucket, name): self.bucket = bucket self.name = name self.data = None self.size = 0 self.BufferSize = 1024 def close(self): pass def exists(self): return self.bucket.exists(self.name) def delete(self): self.bucket.delete(self.name) def compute_md5(self, data): chunk = data.read(self.BufferSize) checksum = hashlib.md5() while chunk: checksum.update(chunk) chunk = data.read(self.BufferSize) checksum_hex = checksum.hexdigest() return checksum_hex, None def set_contents_from_file(self, fp, replace=False, **kwargs): self.data = six.StringIO() for bytes in fp: self.data.write(bytes) self.size = self.data.len # Reset the buffer to start self.data.seek(0) self.read = self.data.read def get_file(self): return self.data class FakeBucket: """ Acts like a ``boto.s3.bucket.Bucket`` """ def __init__(self, name, keys=None): self.name = name self.keys = keys or {} def __str__(self): return self.name def exists(self, key): return key in self.keys def delete(self, key): del self.keys[key] def get_key(self, key_name, **kwargs): key = self.keys.get(key_name) if not key: return FakeKey(self, key_name) return key def new_key(self, key_name): new_key = FakeKey(self, key_name) self.keys[key_name] = new_key return new_key fixture_buckets = {'glance': FakeBucket('glance')} b = fixture_buckets['glance'] k = b.new_key(FAKE_UUID) k.set_contents_from_file(six.StringIO("*" * FIVE_KB)) def fake_connection_constructor(self, *args, **kwargs): host = kwargs.get('host') if host.startswith('http://') or host.startswith('https://'): raise UnsupportedBackend(host) def fake_get_bucket(conn, bucket_id): bucket = fixture_buckets.get(bucket_id) if not bucket: bucket = FakeBucket(bucket_id) return bucket stubs.Set(boto.s3.connection.S3Connection, '__init__', fake_connection_constructor) stubs.Set(boto.s3.connection.S3Connection, 'get_bucket', fake_get_bucket) def format_s3_location(user, key, authurl, bucket, obj): """ Helper method that returns a S3 store URI given the component pieces. """ scheme = 's3' if authurl.startswith('https://'): scheme = 's3+https' authurl = authurl[8:] elif authurl.startswith('http://'): authurl = authurl[7:] authurl = authurl.strip('/') return "%s://%s:%s@%s/%s/%s" % (scheme, user, key, authurl, bucket, obj) class TestStore(base.StoreClearingUnitTest): def setUp(self): """Establish a clean test environment""" self.config(**S3_CONF) super(TestStore, self).setUp() self.stubs = stubout.StubOutForTesting() stub_out_s3(self.stubs) self.store = Store() self.addCleanup(self.stubs.UnsetAll) def test_get(self): """Test a "normal" retrieval of an image in chunks""" loc = get_location_from_uri( "s3://user:key@auth_address/glance/%s" % FAKE_UUID) (image_s3, image_size) = self.store.get(loc) self.assertEqual(image_size, FIVE_KB) expected_data = "*" * FIVE_KB data = "" for chunk in image_s3: data += chunk self.assertEqual(expected_data, data) def test_get_calling_format_path(self): """Test a "normal" retrieval of an image in chunks""" self.config(s3_store_bucket_url_format='path') def fake_S3Connection_init(*args, **kwargs): expected_cls = boto.s3.connection.OrdinaryCallingFormat self.assertIsInstance(kwargs.get('calling_format'), expected_cls) self.stubs.Set(boto.s3.connection.S3Connection, '__init__', fake_S3Connection_init) loc = get_location_from_uri( "s3://user:key@auth_address/glance/%s" % FAKE_UUID) (image_s3, image_size) = self.store.get(loc) def test_get_calling_format_default(self): """Test a "normal" retrieval of an image in chunks""" def fake_S3Connection_init(*args, **kwargs): expected_cls = boto.s3.connection.SubdomainCallingFormat self.assertIsInstance(kwargs.get('calling_format'), expected_cls) self.stubs.Set(boto.s3.connection.S3Connection, '__init__', fake_S3Connection_init) loc = get_location_from_uri( "s3://user:key@auth_address/glance/%s" % FAKE_UUID) (image_s3, image_size) = self.store.get(loc) def test_get_non_existing(self): """ Test that trying to retrieve a s3 that doesn't exist raises an error """ uri = "s3://user:key@auth_address/badbucket/%s" % FAKE_UUID loc = get_location_from_uri(uri) self.assertRaises(exception.NotFound, self.store.get, loc) uri = "s3://user:key@auth_address/glance/noexist" loc = get_location_from_uri(uri) self.assertRaises(exception.NotFound, self.store.get, loc) def test_add(self): """Test that we can add an image via the s3 backend""" expected_image_id = str(uuid.uuid4()) expected_s3_size = FIVE_KB expected_s3_contents = "*" * expected_s3_size expected_checksum = hashlib.md5(expected_s3_contents).hexdigest() expected_location = format_s3_location( S3_CONF['s3_store_access_key'], S3_CONF['s3_store_secret_key'], S3_CONF['s3_store_host'], S3_CONF['s3_store_bucket'], expected_image_id) image_s3 = six.StringIO(expected_s3_contents) location, size, checksum, _ = self.store.add(expected_image_id, image_s3, expected_s3_size) self.assertEqual(expected_location, location) self.assertEqual(expected_s3_size, size) self.assertEqual(expected_checksum, checksum) loc = get_location_from_uri(expected_location) (new_image_s3, new_image_size) = self.store.get(loc) new_image_contents = six.StringIO() for chunk in new_image_s3: new_image_contents.write(chunk) new_image_s3_size = new_image_contents.len self.assertEqual(expected_s3_contents, new_image_contents.getvalue()) self.assertEqual(expected_s3_size, new_image_s3_size) def test_add_host_variations(self): """ Test that having http(s):// in the s3serviceurl in config options works as expected. """ variations = ['http://localhost:80', 'http://localhost', 'http://localhost/v1', 'http://localhost/v1/', 'https://localhost', 'https://localhost:8080', 'https://localhost/v1', 'https://localhost/v1/', 'localhost', 'localhost:8080/v1'] for variation in variations: expected_image_id = str(uuid.uuid4()) expected_s3_size = FIVE_KB expected_s3_contents = "*" * expected_s3_size expected_checksum = hashlib.md5(expected_s3_contents).hexdigest() new_conf = S3_CONF.copy() new_conf['s3_store_host'] = variation expected_location = format_s3_location( new_conf['s3_store_access_key'], new_conf['s3_store_secret_key'], new_conf['s3_store_host'], new_conf['s3_store_bucket'], expected_image_id) image_s3 = six.StringIO(expected_s3_contents) self.config(**new_conf) self.store = Store() location, size, checksum, _ = self.store.add(expected_image_id, image_s3, expected_s3_size) self.assertEqual(expected_location, location) self.assertEqual(expected_s3_size, size) self.assertEqual(expected_checksum, checksum) loc = get_location_from_uri(expected_location) (new_image_s3, new_image_size) = self.store.get(loc) new_image_contents = new_image_s3.getvalue() new_image_s3_size = len(new_image_s3) self.assertEqual(expected_s3_contents, new_image_contents) self.assertEqual(expected_s3_size, new_image_s3_size) def test_add_already_existing(self): """ Tests that adding an image with an existing identifier raises an appropriate exception """ image_s3 = six.StringIO("nevergonnamakeit") self.assertRaises(exception.Duplicate, self.store.add, FAKE_UUID, image_s3, 0) def _option_required(self, key): conf = S3_CONF.copy() conf[key] = None try: self.config(**conf) self.store = Store() return self.store.add == self.store.add_disabled except Exception: return False return False def test_no_access_key(self): """ Tests that options without access key disables the add method """ self.assertTrue(self._option_required('s3_store_access_key')) def test_no_secret_key(self): """ Tests that options without secret key disables the add method """ self.assertTrue(self._option_required('s3_store_secret_key')) def test_no_host(self): """ Tests that options without host disables the add method """ self.assertTrue(self._option_required('s3_store_host')) def test_delete(self): """ Test we can delete an existing image in the s3 store """ uri = "s3://user:key@auth_address/glance/%s" % FAKE_UUID loc = get_location_from_uri(uri) self.store.delete(loc) self.assertRaises(exception.NotFound, self.store.get, loc) def test_delete_non_existing(self): """ Test that trying to delete a s3 that doesn't exist raises an error """ uri = "s3://user:key@auth_address/glance/noexist" loc = get_location_from_uri(uri) self.assertRaises(exception.NotFound, self.store.delete, loc) def _do_test_get_s3_location(self, host, loc): self.assertEqual(get_s3_location(host), loc) self.assertEqual(get_s3_location(host + ':80'), loc) self.assertEqual(get_s3_location('http://' + host), loc) self.assertEqual(get_s3_location('http://' + host + ':80'), loc) self.assertEqual(get_s3_location('https://' + host), loc) self.assertEqual(get_s3_location('https://' + host + ':80'), loc) def test_get_s3_good_location(self): """ Test that the s3 location can be derived from the host """ good_locations = [ ('s3.amazonaws.com', ''), ('s3-eu-west-1.amazonaws.com', 'EU'), ('s3-us-west-1.amazonaws.com', 'us-west-1'), ('s3-ap-southeast-1.amazonaws.com', 'ap-southeast-1'), ('s3-ap-northeast-1.amazonaws.com', 'ap-northeast-1'), ] for (url, expected) in good_locations: self._do_test_get_s3_location(url, expected) def test_get_s3_bad_location(self): """ Test that the s3 location cannot be derived from an unexpected host """ bad_locations = [ ('', ''), ('s3.amazon.co.uk', ''), ('s3-govcloud.amazonaws.com', ''), ('cloudfiles.rackspace.com', ''), ] for (url, expected) in bad_locations: self._do_test_get_s3_location(url, expected) def test_calling_format_path(self): self.config(s3_store_bucket_url_format='path') self.assertIsInstance(glance.store.s3.get_calling_format(), boto.s3.connection.OrdinaryCallingFormat) def test_calling_format_subdomain(self): self.config(s3_store_bucket_url_format='subdomain') self.assertIsInstance(glance.store.s3.get_calling_format(), boto.s3.connection.SubdomainCallingFormat) def test_calling_format_default(self): self.assertIsInstance(glance.store.s3.get_calling_format(), boto.s3.connection.SubdomainCallingFormat) glance-2014.1/glance/tests/unit/test_migrations.py0000664000175400017540000015040012323736230023330 0ustar jenkinsjenkins00000000000000# Copyright 2010-2011 OpenStack Foundation # All Rights Reserved. # Copyright 2013 IBM Corp. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ Tests for database migrations. This test case reads the configuration file /tests/unit/test_migrations.conf for database connection settings to use in the tests. For each connection found in the config file, the test case runs a series of test cases to ensure that migrations work properly both upgrading and downgrading, and that no data loss occurs if possible. """ from __future__ import print_function import ConfigParser import datetime import exceptions import os import pickle import subprocess import uuid from migrate.versioning import api as migration_api from migrate.versioning.repository import Repository from oslo.config import cfg import six.moves.urllib.parse as urlparse from six.moves import xrange import sqlalchemy from glance.common import crypt from glance.common import exception from glance.common import utils import glance.db.migration as migration import glance.db.sqlalchemy.migrate_repo from glance.db.sqlalchemy.migrate_repo.schema import from_migration_import from glance.db.sqlalchemy import models from glance.openstack.common import jsonutils from glance.openstack.common import log as logging from glance.openstack.common import timeutils from glance.tests import utils as test_utils CONF = cfg.CONF CONF.import_opt('metadata_encryption_key', 'glance.common.config') LOG = logging.getLogger(__name__) def _get_connect_string(backend, user="openstack_citest", passwd="openstack_citest", database="openstack_citest"): """ Try to get a connection with a very specific set of values, if we get these then we'll run the tests, otherwise they are skipped """ if backend == "mysql": backend = "mysql+mysqldb" elif backend == "postgres": backend = "postgresql+psycopg2" return ("%(backend)s://%(user)s:%(passwd)s@localhost/%(database)s" % {'backend': backend, 'user': user, 'passwd': passwd, 'database': database}) def _is_backend_avail(backend, user="openstack_citest", passwd="openstack_citest", database="openstack_citest"): try: if backend == "mysql": connect_uri = _get_connect_string("mysql", user=user, passwd=passwd, database=database) elif backend == "postgres": connect_uri = _get_connect_string("postgres", user=user, passwd=passwd, database=database) engine = sqlalchemy.create_engine(connect_uri) connection = engine.connect() except Exception: # intentionally catch all to handle exceptions even if we don't # have any backend code loaded. return False else: connection.close() engine.dispose() return True def _have_mysql(): present = os.environ.get('GLANCE_TEST_MYSQL_PRESENT') if present is None: return _is_backend_avail('mysql') return present.lower() in ('', 'true') def get_table(engine, name): """Returns an sqlalchemy table dynamically from db. Needed because the models don't work for us in migrations as models will be far out of sync with the current data. """ metadata = sqlalchemy.schema.MetaData() metadata.bind = engine return sqlalchemy.Table(name, metadata, autoload=True) class TestMigrations(test_utils.BaseTestCase): """Test sqlalchemy-migrate migrations.""" DEFAULT_CONFIG_FILE = os.path.join(os.path.dirname(__file__), 'test_migrations.conf') # Test machines can set the GLANCE_TEST_MIGRATIONS_CONF variable # to override the location of the config file for migration testing CONFIG_FILE_PATH = os.environ.get('GLANCE_TEST_MIGRATIONS_CONF', DEFAULT_CONFIG_FILE) MIGRATE_FILE = glance.db.sqlalchemy.migrate_repo.__file__ REPOSITORY = Repository(os.path.abspath(os.path.dirname(MIGRATE_FILE))) def setUp(self): super(TestMigrations, self).setUp() self.snake_walk = False self.test_databases = {} # Load test databases from the config file. Only do this # once. No need to re-run this on each test... LOG.debug('config_path is %s' % TestMigrations.CONFIG_FILE_PATH) if os.path.exists(TestMigrations.CONFIG_FILE_PATH): cp = ConfigParser.RawConfigParser() try: cp.read(TestMigrations.CONFIG_FILE_PATH) defaults = cp.defaults() for key, value in defaults.items(): self.test_databases[key] = value self.snake_walk = cp.getboolean('walk_style', 'snake_walk') except ConfigParser.ParsingError as e: self.fail("Failed to read test_migrations.conf config " "file. Got error: %s" % e) else: self.fail("Failed to find test_migrations.conf config " "file.") self.engines = {} for key, value in self.test_databases.items(): self.engines[key] = sqlalchemy.create_engine(value) # We start each test case with a completely blank slate. self._reset_databases() def tearDown(self): # We destroy the test data store between each test case, # and recreate it, which ensures that we have no side-effects # from the tests self._reset_databases() super(TestMigrations, self).tearDown() def _reset_databases(self): def execute_cmd(cmd=None): proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True) output = proc.communicate()[0] LOG.debug(output) self.assertEqual(0, proc.returncode) for key, engine in self.engines.items(): conn_string = self.test_databases[key] conn_pieces = urlparse.urlparse(conn_string) engine.dispose() if conn_string.startswith('sqlite'): # We can just delete the SQLite database, which is # the easiest and cleanest solution db_path = conn_pieces.path[1:] if os.path.exists(db_path): os.unlink(db_path) # No need to recreate the SQLite DB. SQLite will # create it for us if it's not there... elif conn_string.startswith('mysql'): # We can execute the MySQL client to destroy and re-create # the MYSQL database, which is easier and less error-prone # than using SQLAlchemy to do this via MetaData...trust me. database = conn_pieces.path.strip('/') loc_pieces = conn_pieces.netloc.split('@') host = loc_pieces[1] auth_pieces = loc_pieces[0].split(':') user = auth_pieces[0] password = "" if len(auth_pieces) > 1: if auth_pieces[1].strip(): password = "-p\"%s\"" % auth_pieces[1] sql = ("drop database if exists %(database)s; create " "database %(database)s;") % {'database': database} cmd = ("mysql -u \"%(user)s\" %(password)s -h %(host)s " "-e \"%(sql)s\"") % {'user': user, 'password': password, 'host': host, 'sql': sql} execute_cmd(cmd) elif conn_string.startswith('postgresql'): database = conn_pieces.path.strip('/') loc_pieces = conn_pieces.netloc.split('@') host = loc_pieces[1] auth_pieces = loc_pieces[0].split(':') user = auth_pieces[0] password = "" if len(auth_pieces) > 1: password = auth_pieces[1].strip() # note(boris-42): This file is used for authentication # without password prompt. createpgpass = ("echo '*:*:*:%(user)s:%(password)s' > " "~/.pgpass && chmod 0600 ~/.pgpass" % {'user': user, 'password': password}) execute_cmd(createpgpass) # note(boris-42): We must create and drop database, we can't # drop database which we have connected to, so for such # operations there is a special database template1. sqlcmd = ("psql -w -U %(user)s -h %(host)s -c" " '%(sql)s' -d template1") sql = ("drop database if exists %(database)s;") sql = sql % {'database': database} droptable = sqlcmd % {'user': user, 'host': host, 'sql': sql} execute_cmd(droptable) sql = ("create database %(database)s;") sql = sql % {'database': database} createtable = sqlcmd % {'user': user, 'host': host, 'sql': sql} execute_cmd(createtable) def test_walk_versions(self): """ Walks all version scripts for each tested database, ensuring that there are no errors in the version scripts for each engine """ for key, engine in self.engines.items(): self._walk_versions(engine, self.snake_walk) def test_mysql_connect_fail(self): """ Test that we can trigger a mysql connection failure and we fail gracefully to ensure we don't break people without mysql """ if _is_backend_avail('mysql', user="openstack_cifail"): self.fail("Shouldn't have connected") def test_mysql_opportunistically(self): # Test that table creation on mysql only builds InnoDB tables if not _is_backend_avail('mysql'): self.skipTest("mysql not available") # add this to the global lists to make reset work with it, it's removed # automatically in tearDown so no need to clean it up here. connect_string = _get_connect_string("mysql") engine = sqlalchemy.create_engine(connect_string) self.engines["mysqlcitest"] = engine self.test_databases["mysqlcitest"] = connect_string # build a fully populated mysql database with all the tables self._reset_databases() self._walk_versions(engine, False, False) connection = engine.connect() # sanity check total = connection.execute("SELECT count(*) " "from information_schema.TABLES " "where TABLE_SCHEMA='openstack_citest'") self.assertTrue(total.scalar() > 0, "No tables found. Wrong schema?") noninnodb = connection.execute("SELECT count(*) " "from information_schema.TABLES " "where TABLE_SCHEMA='openstack_citest' " "and ENGINE!='InnoDB' " "and TABLE_NAME!='migrate_version'") count = noninnodb.scalar() self.assertEqual(count, 0, "%d non InnoDB tables created" % count) connection.close() def test_postgresql_connect_fail(self): """ Test that we can trigger a postgres connection failure and we fail gracefully to ensure we don't break people without postgres """ if _is_backend_avail('postgresql', user="openstack_cifail"): self.fail("Shouldn't have connected") def test_postgresql_opportunistically(self): # Test postgresql database migration walk if not _is_backend_avail('postgres'): self.skipTest("postgresql not available") # add this to the global lists to make reset work with it, it's removed # automatically in tearDown so no need to clean it up here. connect_string = _get_connect_string("postgres") engine = sqlalchemy.create_engine(connect_string) self.engines["postgresqlcitest"] = engine self.test_databases["postgresqlcitest"] = connect_string # build a fully populated postgresql database with all the tables self._reset_databases() self._walk_versions(engine, False, False) def _walk_versions(self, engine=None, snake_walk=False, downgrade=True, initial_version=None): # Determine latest version script from the repo, then # upgrade from 1 through to the latest, with no data # in the databases. This just checks that the schema itself # upgrades successfully. def db_version(): return migration_api.db_version(engine, TestMigrations.REPOSITORY) # Place the database under version control init_version = migration.INIT_VERSION if initial_version is not None: init_version = initial_version migration_api.version_control(engine, TestMigrations.REPOSITORY, init_version) self.assertEqual(init_version, db_version()) migration_api.upgrade(engine, TestMigrations.REPOSITORY, init_version + 1) self.assertEqual(init_version + 1, db_version()) LOG.debug('latest version is %s' % TestMigrations.REPOSITORY.latest) for version in xrange(init_version + 2, TestMigrations.REPOSITORY.latest + 1): # upgrade -> downgrade -> upgrade self._migrate_up(engine, version, with_data=True) if snake_walk: self._migrate_down(engine, version - 1, with_data=True) self._migrate_up(engine, version) if downgrade: # Now walk it back down to 0 from the latest, testing # the downgrade paths. for version in reversed( xrange(init_version + 2, TestMigrations.REPOSITORY.latest + 1)): # downgrade -> upgrade -> downgrade self._migrate_down(engine, version - 1) if snake_walk: self._migrate_up(engine, version) self._migrate_down(engine, version - 1) # Ensure we made it all the way back to the first migration self.assertEqual(init_version + 1, db_version()) def _migrate_down(self, engine, version, with_data=False): migration_api.downgrade(engine, TestMigrations.REPOSITORY, version) self.assertEqual(version, migration_api.db_version(engine, TestMigrations.REPOSITORY)) # NOTE(sirp): `version` is what we're downgrading to (i.e. the 'target' # version). So if we have any downgrade checks, they need to be run for # the previous (higher numbered) migration. if with_data: post_downgrade = getattr(self, "_post_downgrade_%03d" % (version + 1), None) if post_downgrade: post_downgrade(engine) def _migrate_up(self, engine, version, with_data=False): """migrate up to a new version of the db. We allow for data insertion and post checks at every migration version with special _pre_upgrade_### and _check_### functions in the main test. """ if with_data: data = None pre_upgrade = getattr(self, "_pre_upgrade_%3.3d" % version, None) if pre_upgrade: data = pre_upgrade(engine) migration_api.upgrade(engine, TestMigrations.REPOSITORY, version) self.assertEqual(version, migration_api.db_version(engine, TestMigrations.REPOSITORY)) if with_data: check = getattr(self, "_check_%3.3d" % version, None) if check: check(engine, data) def _create_unversioned_001_db(self, engine): # Create the initial version of the images table meta = sqlalchemy.schema.MetaData() meta.bind = engine images_001 = sqlalchemy.Table('images', meta, sqlalchemy.Column('id', models.Integer, primary_key=True), sqlalchemy.Column('name', sqlalchemy.String(255) ), sqlalchemy.Column('type', sqlalchemy.String(30)), sqlalchemy.Column('size', sqlalchemy.Integer), sqlalchemy.Column('status', sqlalchemy.String(30)), sqlalchemy.Column('is_public', sqlalchemy.Boolean, default=False), sqlalchemy.Column('location', sqlalchemy.Text), sqlalchemy.Column('created_at', sqlalchemy.DateTime(), nullable=False), sqlalchemy.Column('updated_at', sqlalchemy.DateTime()), sqlalchemy.Column('deleted_at', sqlalchemy.DateTime()), sqlalchemy.Column('deleted', sqlalchemy.Boolean(), nullable=False, default=False)) images_001.create() def test_version_control_existing_db(self): """ Creates a DB without version control information, places it under version control and checks that it can be upgraded without errors. """ for key, engine in self.engines.items(): self._create_unversioned_001_db(engine) self._walk_versions(engine, self.snake_walk, initial_version=1) def _pre_upgrade_003(self, engine): now = datetime.datetime.now() images = get_table(engine, 'images') data = {'deleted': False, 'created_at': now, 'updated_at': now, 'type': 'kernel', 'status': 'active', 'is_public': True} images.insert().values(data).execute() return data def _check_003(self, engine, data): images = get_table(engine, 'images') self.assertTrue('type' not in images.c, "'type' column found in images table columns! " "images table columns reported by metadata: %s\n" % images.c.keys()) images_prop = get_table(engine, 'image_properties') result = images_prop.select().execute() types = [] for row in result: if row['key'] == 'type': types.append(row['value']) self.assertIn(data['type'], types) def _pre_upgrade_004(self, engine): """Insert checksum data sample to check if migration goes fine with data. """ now = timeutils.utcnow() images = get_table(engine, 'images') data = [ { 'deleted': False, 'created_at': now, 'updated_at': now, 'type': 'kernel', 'status': 'active', 'is_public': True, } ] engine.execute(images.insert(), data) return data def _check_004(self, engine, data): """Assure that checksum data is present on table""" images = get_table(engine, 'images') self.assertIn('checksum', images.c) self.assertEqual(images.c['checksum'].type.length, 32) def _pre_upgrade_005(self, engine): now = timeutils.utcnow() images = get_table(engine, 'images') data = [ { 'deleted': False, 'created_at': now, 'updated_at': now, 'type': 'kernel', 'status': 'active', 'is_public': True, # Integer type signed size limit 'size': 2147483647 } ] engine.execute(images.insert(), data) return data def _check_005(self, engine, data): images = get_table(engine, 'images') select = images.select().execute() sizes = [row['size'] for row in select if row['size'] is not None] migrated_data_sizes = [element['size'] for element in data] for migrated in migrated_data_sizes: self.assertIn(migrated, sizes) def _pre_upgrade_006(self, engine): now = timeutils.utcnow() images = get_table(engine, 'images') image_data = [ { 'deleted': False, 'created_at': now, 'updated_at': now, 'type': 'kernel', 'status': 'active', 'is_public': True, 'id': 9999, } ] engine.execute(images.insert(), image_data) images_properties = get_table(engine, 'image_properties') properties_data = [ { 'id': 10, 'image_id': 9999, 'updated_at': now, 'created_at': now, 'deleted': False, 'key': 'image_name' } ] engine.execute(images_properties.insert(), properties_data) return properties_data def _check_006(self, engine, data): images_properties = get_table(engine, 'image_properties') select = images_properties.select().execute() # load names from name collumn image_names = [row['name'] for row in select] # check names from data in image names from name collumn for element in data: self.assertIn(element['key'], image_names) def _pre_upgrade_010(self, engine): """Test rows in images with NULL updated_at get updated to equal created_at. """ initial_values = [ (datetime.datetime(1999, 1, 2, 4, 10, 20), datetime.datetime(1999, 1, 2, 4, 10, 30)), (datetime.datetime(1999, 2, 4, 6, 15, 25), datetime.datetime(1999, 2, 4, 6, 15, 35)), (datetime.datetime(1999, 3, 6, 8, 20, 30), None), (datetime.datetime(1999, 4, 8, 10, 25, 35), None), ] images = get_table(engine, 'images') for created_at, updated_at in initial_values: row = dict(deleted=False, created_at=created_at, updated_at=updated_at, status='active', is_public=True, min_disk=0, min_ram=0) images.insert().values(row).execute() return initial_values def _check_010(self, engine, data): values = dict((c, u) for c, u in data) images = get_table(engine, 'images') for row in images.select().execute(): if row['created_at'] in values: # updated_at should be unchanged if not previous NULL, or # set to created_at if previously NULL updated_at = values.pop(row['created_at']) or row['created_at'] self.assertEqual(row['updated_at'], updated_at) # No initial values should be remaining self.assertEqual(len(values), 0) def _pre_upgrade_012(self, engine): """Test rows in images have id changes from int to varchar(32) and value changed from int to UUID. Also test image_members and image_properties gets updated to point to new UUID keys. """ images = get_table(engine, 'images') image_members = get_table(engine, 'image_members') image_properties = get_table(engine, 'image_properties') # Insert kernel, ramdisk and normal images now = timeutils.utcnow() data = {'created_at': now, 'updated_at': now, 'status': 'active', 'deleted': False, 'is_public': True, 'min_disk': 0, 'min_ram': 0} test_data = {} for name in ('kernel', 'ramdisk', 'normal'): data['name'] = '%s migration 012 test' % name result = images.insert().values(data).execute() test_data[name] = result.inserted_primary_key[0] # Insert image_members and image_properties rows data = {'created_at': now, 'updated_at': now, 'deleted': False, 'image_id': test_data['normal'], 'member': 'foobar', 'can_share': False} result = image_members.insert().values(data).execute() test_data['member'] = result.inserted_primary_key[0] data = {'created_at': now, 'updated_at': now, 'deleted': False, 'image_id': test_data['normal'], 'name': 'ramdisk_id', 'value': test_data['ramdisk']} result = image_properties.insert().values(data).execute() test_data['properties'] = [result.inserted_primary_key[0]] data.update({'name': 'kernel_id', 'value': test_data['kernel']}) result = image_properties.insert().values(data).execute() test_data['properties'].append(result.inserted_primary_key) return test_data def _check_012(self, engine, test_data): images = get_table(engine, 'images') image_members = get_table(engine, 'image_members') image_properties = get_table(engine, 'image_properties') # Find kernel, ramdisk and normal images. Make sure id has been # changed to a uuid uuids = {} for name in ('kernel', 'ramdisk', 'normal'): image_name = '%s migration 012 test' % name rows = images.select()\ .where(images.c.name == image_name)\ .execute().fetchall() self.assertEqual(len(rows), 1) row = rows[0] self.assertTrue(utils.is_uuid_like(row['id'])) uuids[name] = row['id'] # Find all image_members to ensure image_id has been updated results = image_members.select()\ .where(image_members.c.image_id == uuids['normal'])\ .execute().fetchall() self.assertEqual(len(results), 1) # Find all image_properties to ensure image_id has been updated # as well as ensure kernel_id and ramdisk_id values have been # updated too results = image_properties.select()\ .where(image_properties.c.image_id == uuids['normal'])\ .execute().fetchall() self.assertEqual(len(results), 2) for row in results: self.assertIn(row['name'], ('kernel_id', 'ramdisk_id')) if row['name'] == 'kernel_id': self.assertEqual(row['value'], uuids['kernel']) if row['name'] == 'ramdisk_id': self.assertEqual(row['value'], uuids['ramdisk']) def _post_downgrade_012(self, engine): images = get_table(engine, 'images') image_members = get_table(engine, 'image_members') image_properties = get_table(engine, 'image_properties') # Find kernel, ramdisk and normal images. Make sure id has been # changed back to an integer ids = {} for name in ('kernel', 'ramdisk', 'normal'): image_name = '%s migration 012 test' % name rows = images.select()\ .where(images.c.name == image_name)\ .execute().fetchall() self.assertEqual(len(rows), 1) row = rows[0] self.assertFalse(utils.is_uuid_like(row['id'])) ids[name] = row['id'] # Find all image_members to ensure image_id has been updated results = image_members.select()\ .where(image_members.c.image_id == ids['normal'])\ .execute().fetchall() self.assertEqual(len(results), 1) # Find all image_properties to ensure image_id has been updated # as well as ensure kernel_id and ramdisk_id values have been # updated too results = image_properties.select()\ .where(image_properties.c.image_id == ids['normal'])\ .execute().fetchall() self.assertEqual(len(results), 2) for row in results: self.assertIn(row['name'], ('kernel_id', 'ramdisk_id')) if row['name'] == 'kernel_id': self.assertEqual(row['value'], str(ids['kernel'])) if row['name'] == 'ramdisk_id': self.assertEqual(row['value'], str(ids['ramdisk'])) def _assert_invalid_swift_uri_raises_bad_store_uri(self, legacy_parse_uri_fn): invalid_uri = ('swift://http://acct:usr:pass@example.com' '/container/obj-id') # URI cannot contain more than one occurrence of a scheme. self.assertRaises(exception.BadStoreUri, legacy_parse_uri_fn, invalid_uri, True) invalid_scheme_uri = ('http://acct:usr:pass@example.com' '/container/obj-id') self.assertRaises(exceptions.AssertionError, legacy_parse_uri_fn, invalid_scheme_uri, True) invalid_account_missing_uri = 'swift+http://container/obj-id' # Badly formed S3 URI: swift+http://container/obj-id self.assertRaises(exception.BadStoreUri, legacy_parse_uri_fn, invalid_account_missing_uri, True) invalid_container_missing_uri = ('swift+http://' 'acct:usr:pass@example.com/obj-id') # Badly formed S3 URI: swift+http://acct:usr:pass@example.com/obj-id self.assertRaises(exception.BadStoreUri, legacy_parse_uri_fn, invalid_container_missing_uri, True) invalid_object_missing_uri = ('swift+http://' 'acct:usr:pass@example.com/container') # Badly formed S3 URI: swift+http://acct:usr:pass@example.com/container self.assertRaises(exception.BadStoreUri, legacy_parse_uri_fn, invalid_object_missing_uri, True) invalid_user_without_pass_uri = ('swift://acctusr@example.com' '/container/obj-id') # Badly formed credentials '%(creds)s' in Swift URI self.assertRaises(exception.BadStoreUri, legacy_parse_uri_fn, invalid_user_without_pass_uri, True) # Badly formed credentials in Swift URI. self.assertRaises(exception.BadStoreUri, legacy_parse_uri_fn, invalid_user_without_pass_uri, False) def test_legacy_parse_swift_uri_015(self): (legacy_parse_uri,) = from_migration_import( '015_quote_swift_credentials', ['legacy_parse_uri']) uri = legacy_parse_uri( 'swift://acct:usr:pass@example.com/container/obj-id', True) self.assertTrue(uri, 'swift://acct%3Ausr:pass@example.com' '/container/obj-id') self._assert_invalid_swift_uri_raises_bad_store_uri(legacy_parse_uri) def _pre_upgrade_015(self, engine): images = get_table(engine, 'images') unquoted_locations = [ 'swift://acct:usr:pass@example.com/container/obj-id', 'file://foo', ] now = datetime.datetime.now() temp = dict(deleted=False, created_at=now, updated_at=now, status='active', is_public=True, min_disk=0, min_ram=0) data = [] for i, location in enumerate(unquoted_locations): temp.update(location=location, id=str(uuid.uuid4())) data.append(temp) images.insert().values(temp).execute() return data def _check_015(self, engine, data): images = get_table(engine, 'images') quoted_locations = [ 'swift://acct%3Ausr:pass@example.com/container/obj-id', 'file://foo', ] result = images.select().execute() locations = map(lambda x: x['location'], result) for loc in quoted_locations: self.assertIn(loc, locations) def _pre_upgrade_016(self, engine): images = get_table(engine, 'images') now = datetime.datetime.now() temp = dict(deleted=False, created_at=now, updated_at=now, status='active', is_public=True, min_disk=0, min_ram=0, id='fake-image-id1') images.insert().values(temp).execute() image_members = get_table(engine, 'image_members') now = datetime.datetime.now() data = {'deleted': False, 'created_at': now, 'member': 'fake-member', 'updated_at': now, 'can_share': False, 'image_id': 'fake-image-id1'} image_members.insert().values(data).execute() return data def _check_016(self, engine, data): image_members = get_table(engine, 'image_members') self.assertTrue('status' in image_members.c, "'status' column found in image_members table " "columns! image_members table columns: %s" % image_members.c.keys()) def test_legacy_parse_swift_uri_017(self): metadata_encryption_key = 'a' * 16 self.config(metadata_encryption_key=metadata_encryption_key) (legacy_parse_uri, encrypt_location) = from_migration_import( '017_quote_encrypted_swift_credentials', ['legacy_parse_uri', 'encrypt_location']) uri = legacy_parse_uri('swift://acct:usr:pass@example.com' '/container/obj-id', True) self.assertTrue(uri, encrypt_location( 'swift://acct%3Ausr:pass@example.com/container/obj-id')) self._assert_invalid_swift_uri_raises_bad_store_uri(legacy_parse_uri) def _pre_upgrade_017(self, engine): metadata_encryption_key = 'a' * 16 self.config(metadata_encryption_key=metadata_encryption_key) images = get_table(engine, 'images') unquoted = 'swift://acct:usr:pass@example.com/container/obj-id' encrypted_unquoted = crypt.urlsafe_encrypt( metadata_encryption_key, unquoted, 64) data = [] now = datetime.datetime.now() temp = dict(deleted=False, created_at=now, updated_at=now, status='active', is_public=True, min_disk=0, min_ram=0, location=encrypted_unquoted, id='fakeid1') images.insert().values(temp).execute() locations = [ 'file://ab', 'file://abc', 'swift://acct3A%foobar:pass@example.com/container/obj-id2' ] now = datetime.datetime.now() temp = dict(deleted=False, created_at=now, updated_at=now, status='active', is_public=True, min_disk=0, min_ram=0) for i, location in enumerate(locations): temp.update(location=location, id=str(uuid.uuid4())) data.append(temp) images.insert().values(temp).execute() return data def _check_017(self, engine, data): metadata_encryption_key = 'a' * 16 quoted = 'swift://acct%3Ausr:pass@example.com/container/obj-id' images = get_table(engine, 'images') result = images.select().execute() locations = map(lambda x: x['location'], result) actual_location = [] for location in locations: if location: try: temp_loc = crypt.urlsafe_decrypt(metadata_encryption_key, location) actual_location.append(temp_loc) except TypeError: actual_location.append(location) except ValueError: actual_location.append(location) self.assertIn(quoted, actual_location) loc_list = ['file://ab', 'file://abc', 'swift://acct3A%foobar:pass@example.com/container/obj-id2'] for location in loc_list: if location not in actual_location: self.fail(_("location: %s data lost") % location) def _pre_upgrade_019(self, engine): images = get_table(engine, 'images') now = datetime.datetime.now() base_values = { 'deleted': False, 'created_at': now, 'updated_at': now, 'status': 'active', 'is_public': True, 'min_disk': 0, 'min_ram': 0, } data = [ {'id': 'fake-19-1', 'location': 'http://glance.example.com'}, #NOTE(bcwaldon): images with a location of None should # not be migrated {'id': 'fake-19-2', 'location': None}, ] map(lambda image: image.update(base_values), data) for image in data: images.insert().values(image).execute() return data def _check_019(self, engine, data): image_locations = get_table(engine, 'image_locations') records = image_locations.select().execute().fetchall() locations = dict([(il.image_id, il.value) for il in records]) self.assertEqual(locations.get('fake-19-1'), 'http://glance.example.com') def _check_020(self, engine, data): images = get_table(engine, 'images') self.assertFalse('location' in images.c) def _pre_upgrade_026(self, engine): image_locations = get_table(engine, 'image_locations') now = datetime.datetime.now() image_id = 'fake_id' url = 'file:///some/place/onthe/fs' images = get_table(engine, 'images') temp = dict(deleted=False, created_at=now, updated_at=now, status='active', is_public=True, min_disk=0, min_ram=0, id=image_id) images.insert().values(temp).execute() temp = dict(deleted=False, created_at=now, updated_at=now, image_id=image_id, value=url) image_locations.insert().values(temp).execute() return image_id def _check_026(self, engine, data): image_locations = get_table(engine, 'image_locations') results = image_locations.select()\ .where(image_locations.c.image_id == data).execute() r = list(results) self.assertEqual(len(r), 1) self.assertEqual(r[0]['value'], 'file:///some/place/onthe/fs') self.assertTrue('meta_data' in r[0]) x = pickle.loads(r[0]['meta_data']) self.assertEqual(x, {}) def _check_027(self, engine, data): table = "images" index = "checksum_image_idx" columns = ["checksum"] meta = sqlalchemy.MetaData() meta.bind = engine new_table = sqlalchemy.Table(table, meta, autoload=True) index_data = [(idx.name, idx.columns.keys()) for idx in new_table.indexes] self.assertIn((index, columns), index_data) def _check_028(self, engine, data): owner_index = "owner_image_idx" columns = ["owner"] images_table = get_table(engine, 'images') index_data = [(idx.name, idx.columns.keys()) for idx in images_table.indexes if idx.name == owner_index] self.assertIn((owner_index, columns), index_data) def _post_downgrade_028(self, engine): owner_index = "owner_image_idx" columns = ["owner"] images_table = get_table(engine, 'images') index_data = [(idx.name, idx.columns.keys()) for idx in images_table.indexes if idx.name == owner_index] self.assertNotIn((owner_index, columns), index_data) def _pre_upgrade_029(self, engine): image_locations = get_table(engine, 'image_locations') meta_data = {'somelist': ['a', 'b', 'c'], 'avalue': 'hello', 'adict': {}} now = datetime.datetime.now() image_id = 'fake_029_id' url = 'file:///some/place/onthe/fs029' images = get_table(engine, 'images') temp = dict(deleted=False, created_at=now, updated_at=now, status='active', is_public=True, min_disk=0, min_ram=0, id=image_id) images.insert().values(temp).execute() pickle_md = pickle.dumps(meta_data) temp = dict(deleted=False, created_at=now, updated_at=now, image_id=image_id, value=url, meta_data=pickle_md) image_locations.insert().values(temp).execute() return meta_data, image_id def _check_029(self, engine, data): meta_data = data[0] image_id = data[1] image_locations = get_table(engine, 'image_locations') records = image_locations.select().\ where(image_locations.c.image_id == image_id).execute().fetchall() for r in records: d = jsonutils.loads(r['meta_data']) self.assertEqual(d, meta_data) def _post_downgrade_029(self, engine): image_id = 'fake_029_id' image_locations = get_table(engine, 'image_locations') records = image_locations.select().\ where(image_locations.c.image_id == image_id).execute().fetchall() for r in records: md = r['meta_data'] d = pickle.loads(md) self.assertIsInstance(d, dict) def _check_030(self, engine, data): table = "tasks" index_type = ('ix_tasks_type', ['type']) index_status = ('ix_tasks_status', ['status']) index_owner = ('ix_tasks_owner', ['owner']) index_deleted = ('ix_tasks_deleted', ['deleted']) index_updated_at = ('ix_tasks_updated_at', ['updated_at']) meta = sqlalchemy.MetaData() meta.bind = engine tasks_table = sqlalchemy.Table(table, meta, autoload=True) index_data = [(idx.name, idx.columns.keys()) for idx in tasks_table.indexes] self.assertIn(index_type, index_data) self.assertIn(index_status, index_data) self.assertIn(index_owner, index_data) self.assertIn(index_deleted, index_data) self.assertIn(index_updated_at, index_data) expected = [u'id', u'type', u'status', u'owner', u'input', u'result', u'message', u'expires_at', u'created_at', u'updated_at', u'deleted_at', u'deleted'] # NOTE(flwang): Skip the column type checking for now since Jenkins is # using sqlalchemy.dialects.postgresql.base.TIMESTAMP instead of # DATETIME which is using by mysql and sqlite. col_data = [col.name for col in tasks_table.columns] self.assertEqual(expected, col_data) def _post_downgrade_030(self, engine): self.assertRaises(sqlalchemy.exc.NoSuchTableError, get_table, engine, 'tasks') def _pre_upgrade_031(self, engine): images = get_table(engine, 'images') now = datetime.datetime.now() image_id = 'fake_031_id' temp = dict(deleted=False, created_at=now, updated_at=now, status='active', is_public=True, min_disk=0, min_ram=0, id=image_id) images.insert().values(temp).execute() locations_table = get_table(engine, 'image_locations') locations = [ ('file://ab', '{"a": "yo yo"}'), ('file://ab', '{}'), ('file://ab', '{}'), ('file://ab1', '{"a": "that one, please"}'), ('file://ab1', '{"a": "that one, please"}'), ] temp = dict(deleted=False, created_at=now, updated_at=now, image_id=image_id) for location, metadata in locations: temp.update(value=location, meta_data=metadata) locations_table.insert().values(temp).execute() return image_id def _check_031(self, engine, image_id): locations_table = get_table(engine, 'image_locations') result = locations_table.select()\ .where(locations_table.c.image_id == image_id)\ .execute().fetchall() locations = set([(x['value'], x['meta_data']) for x in result]) actual_locations = set([ ('file://ab', '{"a": "yo yo"}'), ('file://ab', '{}'), ('file://ab1', '{"a": "that one, please"}'), ]) self.assertFalse(actual_locations.symmetric_difference(locations)) def _pre_upgrade_032(self, engine): self.assertRaises(sqlalchemy.exc.NoSuchTableError, get_table, engine, 'task_info') tasks = get_table(engine, 'tasks') now = datetime.datetime.now() base_values = { 'deleted': False, 'created_at': now, 'updated_at': now, 'status': 'active', 'owner': 'TENANT', 'type': 'import', } data = [ { 'id': 'task-1', 'input': 'some input', 'message': None, 'result': 'successful' }, { 'id': 'task-2', 'input': None, 'message': None, 'result': None }, ] map(lambda task: task.update(base_values), data) for task in data: tasks.insert().values(task).execute() return data def _check_032(self, engine, data): task_info_table = get_table(engine, 'task_info') task_info_refs = task_info_table.select().execute().fetchall() self.assertEqual(len(task_info_refs), 2) for x in range(len(task_info_refs)): self.assertEqual(task_info_refs[x].task_id, data[x]['id']) self.assertEqual(task_info_refs[x].input, data[x]['input']) self.assertEqual(task_info_refs[x].result, data[x]['result']) self.assertIsNone(task_info_refs[x].message) tasks_table = get_table(engine, 'tasks') self.assertNotIn('input', tasks_table.c) self.assertNotIn('result', tasks_table.c) self.assertNotIn('message', tasks_table.c) def _post_downgrade_032(self, engine): self.assertRaises(sqlalchemy.exc.NoSuchTableError, get_table, engine, 'task_info') tasks_table = get_table(engine, 'tasks') records = tasks_table.select().execute().fetchall() self.assertEqual(len(records), 2) tasks = dict([(t.id, t) for t in records]) task_1 = tasks.get('task-1') self.assertEqual(task_1.input, 'some input') self.assertEqual(task_1.result, 'successful') self.assertIsNone(task_1.message) task_2 = tasks.get('task-2') self.assertIsNone(task_2.input) self.assertIsNone(task_2.result) self.assertIsNone(task_2.message) def _pre_upgrade_033(self, engine): images = get_table(engine, 'images') image_locations = get_table(engine, 'image_locations') now = datetime.datetime.now() image_id = 'fake_id_028_%d' url = 'file:///some/place/onthe/fs_%d' status_list = ['active', 'saving', 'queued', 'killed', 'pending_delete', 'deleted'] image_id_list = [] for (idx, status) in enumerate(status_list): temp = dict(deleted=False, created_at=now, updated_at=now, status=status, is_public=True, min_disk=0, min_ram=0, id=image_id % idx) images.insert().values(temp).execute() temp = dict(deleted=False, created_at=now, updated_at=now, image_id=image_id % idx, value=url % idx) image_locations.insert().values(temp).execute() image_id_list.append(image_id % idx) return image_id_list def _check_033(self, engine, data): image_locations = get_table(engine, 'image_locations') self.assertIn('status', image_locations.c) self.assertEqual(image_locations.c['status'].type.length, 30) status_list = ['active', 'active', 'active', 'deleted', 'pending_delete', 'deleted'] for (idx, image_id) in enumerate(data): results = image_locations.select()\ .where(image_locations.c.image_id == image_id).execute() r = list(results) self.assertEqual(len(r), 1) self.assertTrue('status' in r[0]) self.assertEqual(r[0]['status'], status_list[idx]) def _post_downgrade_033(self, engine): image_locations = get_table(engine, 'image_locations') self.assertNotIn('status', image_locations.c) def _pre_upgrade_034(self, engine): images = get_table(engine, 'images') now = datetime.datetime.now() image_id = 'fake_id_034' temp = dict(deleted=False, created_at=now, updated_at=now, status='active', is_public=True, min_disk=0, min_ram=0, id=image_id) images.insert().values(temp).execute() def _check_034(self, engine, data): images = get_table(engine, 'images') self.assertIn('virtual_size', images.c) result = (images.select() .where(images.c.id == 'fake_id_034') .execute().fetchone()) self.assertIsNone(result.virtual_size) def _post_downgrade_034(self, engine): images = get_table(engine, 'images') self.assertNotIn('virtual_size', images.c) glance-2014.1/glance/tests/unit/__init__.py0000664000175400017540000000000012323736226021647 0ustar jenkinsjenkins00000000000000glance-2014.1/glance/tests/unit/v1/0000775000175400017540000000000012323736427020101 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/tests/unit/v1/test_registry_client.py0000664000175400017540000010725512323736226024727 0ustar jenkinsjenkins00000000000000# Copyright 2010-2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import copy import datetime import os import uuid import mox import testtools from glance.common import client as test_client from glance.common import config from glance.common import exception from glance import context from glance.db.sqlalchemy import api as db_api from glance.openstack.common import timeutils from glance.registry.api.v1.images import Controller as rcontroller import glance.registry.client.v1.api as rapi from glance.registry.client.v1.api import client as rclient from glance.tests.unit import base from glance.tests import utils as test_utils _gen_uuid = lambda: str(uuid.uuid4()) UUID1 = _gen_uuid() UUID2 = _gen_uuid() #NOTE(bcwaldon): needed to init config_dir cli opt config.parse_args(args=[]) class TestRegistryV1Client(base.IsolatedUnitTest, test_utils.RegistryAPIMixIn): """ Test proper actions made for both valid and invalid requests against a Registry service """ def setUp(self): """Establish a clean test environment""" super(TestRegistryV1Client, self).setUp() db_api.get_engine() self.context = context.RequestContext(is_admin=True) self.FIXTURES = [ self.get_fixture( id=UUID1, name='fake image #1', is_public=False, disk_format='ami', container_format='ami', size=13, location="swift://user:passwd@acct/container/obj.tar.0", properties={'type': 'kernel'}), self.get_fixture(id=UUID2, name='fake image #2', properties={}, size=19, location="file:///tmp/glance-tests/2")] self.destroy_fixtures() self.create_fixtures() self.client = rclient.RegistryClient("0.0.0.0") def tearDown(self): """Clear the test environment""" super(TestRegistryV1Client, self).tearDown() self.destroy_fixtures() def test_get_image_index(self): """Test correct set of public image returned""" fixture = { 'id': UUID2, 'name': 'fake image #2' } images = self.client.get_images() self.assertEqualImages(images, (UUID2,), unjsonify=False) for k, v in fixture.items(): self.assertEqual(v, images[0][k]) def test_create_image_with_null_min_disk_min_ram(self): UUID3 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID3, min_disk=None, min_ram=None) db_api.image_create(self.context, extra_fixture) image = self.client.get_image(UUID3) self.assertEqual(0, image["min_ram"]) self.assertEqual(0, image["min_disk"]) def test_get_index_sort_name_asc(self): """ Tests that the /images registry API returns list of public images sorted alphabetically by name in ascending order. """ UUID3 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID3, name='asdf') db_api.image_create(self.context, extra_fixture) UUID4 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID4, name='xyz') db_api.image_create(self.context, extra_fixture) images = self.client.get_images(sort_key='name', sort_dir='asc') self.assertEqualImages(images, (UUID3, UUID2, UUID4), unjsonify=False) def test_get_index_sort_status_desc(self): """ Tests that the /images registry API returns list of public images sorted alphabetically by status in descending order. """ UUID3 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID3, name='asdf', status='queued') db_api.image_create(self.context, extra_fixture) UUID4 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID4, name='xyz') db_api.image_create(self.context, extra_fixture) images = self.client.get_images(sort_key='status', sort_dir='desc') self.assertEqualImages(images, (UUID3, UUID4, UUID2), unjsonify=False) def test_get_index_sort_disk_format_asc(self): """ Tests that the /images registry API returns list of public images sorted alphabetically by disk_format in ascending order. """ UUID3 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID3, name='asdf', disk_format='ami', container_format='ami') db_api.image_create(self.context, extra_fixture) UUID4 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID4, name='xyz', disk_format='vdi') db_api.image_create(self.context, extra_fixture) images = self.client.get_images(sort_key='disk_format', sort_dir='asc') self.assertEqualImages(images, (UUID3, UUID4, UUID2), unjsonify=False) def test_get_index_sort_container_format_desc(self): """ Tests that the /images registry API returns list of public images sorted alphabetically by container_format in descending order. """ UUID3 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID3, name='asdf', disk_format='ami', container_format='ami') db_api.image_create(self.context, extra_fixture) UUID4 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID4, name='xyz', disk_format='iso', container_format='bare') db_api.image_create(self.context, extra_fixture) images = self.client.get_images(sort_key='container_format', sort_dir='desc') self.assertEqualImages(images, (UUID2, UUID4, UUID3), unjsonify=False) def test_get_index_sort_size_asc(self): """ Tests that the /images registry API returns list of public images sorted by size in ascending order. """ UUID3 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID3, name='asdf', disk_format='ami', container_format='ami', size=100) db_api.image_create(self.context, extra_fixture) UUID4 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID4, name='asdf', disk_format='iso', container_format='bare', size=2) db_api.image_create(self.context, extra_fixture) images = self.client.get_images(sort_key='size', sort_dir='asc') self.assertEqualImages(images, (UUID4, UUID2, UUID3), unjsonify=False) def test_get_index_sort_created_at_asc(self): """ Tests that the /images registry API returns list of public images sorted by created_at in ascending order. """ now = timeutils.utcnow() time1 = now + datetime.timedelta(seconds=5) time2 = now UUID3 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID3, created_at=time1) db_api.image_create(self.context, extra_fixture) UUID4 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID4, created_at=time2) db_api.image_create(self.context, extra_fixture) images = self.client.get_images(sort_key='created_at', sort_dir='asc') self.assertEqualImages(images, (UUID2, UUID4, UUID3), unjsonify=False) def test_get_index_sort_updated_at_desc(self): """ Tests that the /images registry API returns list of public images sorted by updated_at in descending order. """ now = timeutils.utcnow() time1 = now + datetime.timedelta(seconds=5) time2 = now UUID3 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID3, created_at=None, updated_at=time1) db_api.image_create(self.context, extra_fixture) UUID4 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID4, created_at=None, updated_at=time2) db_api.image_create(self.context, extra_fixture) images = self.client.get_images(sort_key='updated_at', sort_dir='desc') self.assertEqualImages(images, (UUID3, UUID4, UUID2), unjsonify=False) def test_get_image_index_marker(self): """Test correct set of images returned with marker param.""" UUID3 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID3, name='new name! #123', status='saving') db_api.image_create(self.context, extra_fixture) UUID4 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID4, name='new name! #125', status='saving') db_api.image_create(self.context, extra_fixture) images = self.client.get_images(marker=UUID4) self.assertEqualImages(images, (UUID3, UUID2), unjsonify=False) def test_get_image_index_invalid_marker(self): """Test exception is raised when marker is invalid""" self.assertRaises(exception.Invalid, self.client.get_images, marker=_gen_uuid()) def test_get_image_index_forbidden_marker(self): """Test exception is raised when marker is forbidden""" UUID5 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID5, owner='0123', status='saving', is_public=False) db_api.image_create(self.context, extra_fixture) def non_admin_get_images(self, context, *args, **kwargs): """Convert to non-admin context""" context.is_admin = False rcontroller.__get_images(self, context, *args, **kwargs) rcontroller.__get_images = rcontroller._get_images self.stubs.Set(rcontroller, '_get_images', non_admin_get_images) self.assertRaises(exception.Invalid, self.client.get_images, marker=UUID5) def test_get_image_index_private_marker(self): """Test exception is not raised if private non-owned marker is used""" UUID4 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID4, owner='1234', status='saving', is_public=False) db_api.image_create(self.context, extra_fixture) try: self.client.get_images(marker=UUID4) except Exception as e: self.fail("Unexpected exception '%s'" % e) def test_get_image_index_limit(self): """Test correct number of images returned with limit param.""" extra_fixture = self.get_fixture(id=_gen_uuid(), status='saving') db_api.image_create(self.context, extra_fixture) extra_fixture = self.get_fixture(id=_gen_uuid(), status='saving') db_api.image_create(self.context, extra_fixture) images = self.client.get_images(limit=2) self.assertEqual(len(images), 2) def test_get_image_index_marker_limit(self): """Test correct set of images returned with marker/limit params.""" UUID3 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID3, name='new name! #123', status='saving') db_api.image_create(self.context, extra_fixture) UUID4 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID4, name='new name! #125', status='saving') db_api.image_create(self.context, extra_fixture) images = self.client.get_images(marker=UUID3, limit=1) self.assertEqualImages(images, (UUID2,), unjsonify=False) def test_get_image_index_limit_None(self): """Test correct set of images returned with limit param == None.""" extra_fixture = self.get_fixture(id=_gen_uuid(), status='saving') db_api.image_create(self.context, extra_fixture) extra_fixture = self.get_fixture(id=_gen_uuid(), status='saving') db_api.image_create(self.context, extra_fixture) images = self.client.get_images(limit=None) self.assertEqual(len(images), 3) def test_get_image_index_by_name(self): """ Test correct set of public, name-filtered image returned. This is just a sanity check, we test the details call more in-depth. """ extra_fixture = self.get_fixture(id=_gen_uuid(), name='new name! #123') db_api.image_create(self.context, extra_fixture) images = self.client.get_images(filters={'name': 'new name! #123'}) self.assertEqual(len(images), 1) for image in images: self.assertEqual('new name! #123', image['name']) def test_get_image_details(self): """Tests that the detailed info about public images returned""" fixture = self.get_fixture(id=UUID2, name='fake image #2', properties={}, size=19) images = self.client.get_images_detailed() self.assertEqual(len(images), 1) for k, v in fixture.items(): self.assertEqual(v, images[0][k]) def test_get_image_details_marker_limit(self): """Test correct set of images returned with marker/limit params.""" UUID3 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID3, status='saving') db_api.image_create(self.context, extra_fixture) extra_fixture = self.get_fixture(id=_gen_uuid(), status='saving') db_api.image_create(self.context, extra_fixture) images = self.client.get_images_detailed(marker=UUID3, limit=1) self.assertEqualImages(images, (UUID2,), unjsonify=False) def test_get_image_details_invalid_marker(self): """Test exception is raised when marker is invalid""" self.assertRaises(exception.Invalid, self.client.get_images_detailed, marker=_gen_uuid()) def test_get_image_details_forbidden_marker(self): """Test exception is raised when marker is forbidden""" UUID5 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID5, is_public=False, owner='0123', status='saving') db_api.image_create(self.context, extra_fixture) def non_admin_get_images(self, context, *args, **kwargs): """Convert to non-admin context""" context.is_admin = False rcontroller.__get_images(self, context, *args, **kwargs) rcontroller.__get_images = rcontroller._get_images self.stubs.Set(rcontroller, '_get_images', non_admin_get_images) self.assertRaises(exception.Invalid, self.client.get_images_detailed, marker=UUID5) def test_get_image_details_private_marker(self): """Test exception is not raised if private non-owned marker is used""" UUID4 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID4, is_public=False, owner='1234', status='saving') db_api.image_create(self.context, extra_fixture) try: self.client.get_images_detailed(marker=UUID4) except Exception as e: self.fail("Unexpected exception '%s'" % e) def test_get_image_details_by_name(self): """Tests that a detailed call can be filtered by name""" extra_fixture = self.get_fixture(id=_gen_uuid(), name='new name! #123') db_api.image_create(self.context, extra_fixture) filters = {'name': 'new name! #123'} images = self.client.get_images_detailed(filters=filters) self.assertEqual(len(images), 1) for image in images: self.assertEqual('new name! #123', image['name']) def test_get_image_details_by_status(self): """Tests that a detailed call can be filtered by status""" extra_fixture = self.get_fixture(id=_gen_uuid(), status='saving') db_api.image_create(self.context, extra_fixture) images = self.client.get_images_detailed(filters={'status': 'saving'}) self.assertEqual(len(images), 1) for image in images: self.assertEqual('saving', image['status']) def test_get_image_details_by_container_format(self): """Tests that a detailed call can be filtered by container_format""" extra_fixture = self.get_fixture(id=_gen_uuid(), status='saving') db_api.image_create(self.context, extra_fixture) filters = {'container_format': 'ovf'} images = self.client.get_images_detailed(filters=filters) self.assertEqual(len(images), 2) for image in images: self.assertEqual('ovf', image['container_format']) def test_get_image_details_by_disk_format(self): """Tests that a detailed call can be filtered by disk_format""" extra_fixture = self.get_fixture(id=_gen_uuid(), status='saving') db_api.image_create(self.context, extra_fixture) filters = {'disk_format': 'vhd'} images = self.client.get_images_detailed(filters=filters) self.assertEqual(len(images), 2) for image in images: self.assertEqual('vhd', image['disk_format']) def test_get_image_details_with_maximum_size(self): """Tests that a detailed call can be filtered by size_max""" extra_fixture = self.get_fixture(id=_gen_uuid(), status='saving', size=21) db_api.image_create(self.context, extra_fixture) images = self.client.get_images_detailed(filters={'size_max': 20}) self.assertEqual(len(images), 1) for image in images: self.assertTrue(image['size'] <= 20) def test_get_image_details_with_minimum_size(self): """Tests that a detailed call can be filtered by size_min""" extra_fixture = self.get_fixture(id=_gen_uuid(), status='saving') db_api.image_create(self.context, extra_fixture) images = self.client.get_images_detailed(filters={'size_min': 20}) self.assertEqual(len(images), 1) for image in images: self.assertTrue(image['size'] >= 20) def test_get_image_details_with_changes_since(self): """Tests that a detailed call can be filtered by changes-since""" dt1 = timeutils.utcnow() - datetime.timedelta(1) iso1 = timeutils.isotime(dt1) dt2 = timeutils.utcnow() + datetime.timedelta(1) iso2 = timeutils.isotime(dt2) dt3 = timeutils.utcnow() + datetime.timedelta(2) dt4 = timeutils.utcnow() + datetime.timedelta(3) iso4 = timeutils.isotime(dt4) UUID3 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID3, name='fake image #3') db_api.image_create(self.context, extra_fixture) db_api.image_destroy(self.context, UUID3) UUID4 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID4, name='fake image #4', created_at=dt3, updated_at=dt3) db_api.image_create(self.context, extra_fixture) # Check a standard list, 4 images in db (2 deleted) images = self.client.get_images_detailed(filters={}) self.assertEqualImages(images, (UUID4, UUID2), unjsonify=False) # Expect 3 images (1 deleted) filters = {'changes-since': iso1} images = self.client.get_images(filters=filters) self.assertEqualImages(images, (UUID4, UUID3, UUID2), unjsonify=False) # Expect 1 images (0 deleted) filters = {'changes-since': iso2} images = self.client.get_images_detailed(filters=filters) self.assertEqualImages(images, (UUID4,), unjsonify=False) # Expect 0 images (0 deleted) filters = {'changes-since': iso4} images = self.client.get_images(filters=filters) self.assertEqualImages(images, (), unjsonify=False) def test_get_image_details_with_size_min(self): """Tests that a detailed call can be filtered by size_min""" extra_fixture = self.get_fixture(id=_gen_uuid(), status='saving') db_api.image_create(self.context, extra_fixture) images = self.client.get_images_detailed(filters={'size_min': 20}) self.assertEqual(len(images), 1) for image in images: self.assertTrue(image['size'] >= 20) def test_get_image_details_by_property(self): """Tests that a detailed call can be filtered by a property""" extra_fixture = self.get_fixture(id=_gen_uuid(), status='saving', properties={'p a': 'v a'}) db_api.image_create(self.context, extra_fixture) filters = {'property-p a': 'v a'} images = self.client.get_images_detailed(filters=filters) self.assertEqual(len(images), 1) for image in images: self.assertEqual('v a', image['properties']['p a']) def test_get_image_is_public_v1(self): """Tests that a detailed call can be filtered by a property""" extra_fixture = self.get_fixture(id=_gen_uuid(), status='saving', properties={'is_public': 'avalue'}) context = copy.copy(self.context) db_api.image_create(context, extra_fixture) filters = {'property-is_public': 'avalue'} images = self.client.get_images_detailed(filters=filters) self.assertEqual(len(images), 1) for image in images: self.assertEqual('avalue', image['properties']['is_public']) def test_get_image_details_sort_disk_format_asc(self): """ Tests that a detailed call returns list of public images sorted alphabetically by disk_format in ascending order. """ UUID3 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID3, name='asdf', disk_format='ami', container_format='ami') db_api.image_create(self.context, extra_fixture) UUID4 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID4, name='xyz', disk_format='vdi') db_api.image_create(self.context, extra_fixture) images = self.client.get_images_detailed(sort_key='disk_format', sort_dir='asc') self.assertEqualImages(images, (UUID3, UUID4, UUID2), unjsonify=False) def test_get_image(self): """Tests that the detailed info about an image returned""" fixture = self.get_fixture(id=UUID1, name='fake image #1', disk_format='ami', container_format='ami', is_public=False, size=13, properties={'type': 'kernel'}) data = self.client.get_image(UUID1) for k, v in fixture.items(): el = data[k] self.assertEqual(v, data[k], "Failed v != data[k] where v = %(v)s and " "k = %(k)s and data[k] = %(el)s" % {'v': v, 'k': k, 'el': el}) def test_get_image_non_existing(self): """Tests that NotFound is raised when getting a non-existing image""" self.assertRaises(exception.NotFound, self.client.get_image, _gen_uuid()) def test_add_image_basic(self): """Tests that we can add image metadata and returns the new id""" fixture = self.get_fixture() new_image = self.client.add_image(fixture) # Test all other attributes set data = self.client.get_image(new_image['id']) for k, v in fixture.items(): self.assertEqual(v, data[k]) # Test status was updated properly self.assertTrue('status' in data.keys()) self.assertEqual('active', data['status']) def test_add_image_with_properties(self): """Tests that we can add image metadata with properties""" fixture = self.get_fixture(location="file:///tmp/glance-tests/2", properties={'distro': 'Ubuntu 10.04 LTS'}) new_image = self.client.add_image(fixture) del fixture['location'] for k, v in fixture.items(): self.assertEqual(v, new_image[k]) # Test status was updated properly self.assertTrue('status' in new_image.keys()) self.assertEqual('active', new_image['status']) def test_add_image_with_location_data(self): """Tests that we can add image metadata with properties""" location = "file:///tmp/glance-tests/2" loc_meta = {'key': 'value'} fixture = self.get_fixture(location_data=[{'url': location, 'metadata': loc_meta}], properties={'distro': 'Ubuntu 10.04 LTS'}) new_image = self.client.add_image(fixture) self.assertEqual(new_image['location'], location) self.assertEqual(new_image['location_data'][0]['url'], location) self.assertEqual(new_image['location_data'][0]['metadata'], loc_meta) def test_add_image_with_location_data_with_encryption(self): """Tests that we can add image metadata with properties and enable encryption. """ self.client.metadata_encryption_key = '1234567890123456' location = "file:///tmp/glance-tests/%d" loc_meta = {'key': 'value'} fixture = {'name': 'fake public image', 'is_public': True, 'disk_format': 'vmdk', 'container_format': 'ovf', 'size': 19, 'location_data': [{'url': location % 1, 'metadata': loc_meta}, {'url': location % 2, 'metadata': {}}], 'properties': {'distro': 'Ubuntu 10.04 LTS'}} new_image = self.client.add_image(fixture) self.assertEqual(new_image['location'], location % 1) self.assertEqual(len(new_image['location_data']), 2) self.assertEqual(new_image['location_data'][0]['url'], location % 1) self.assertEqual(new_image['location_data'][0]['metadata'], loc_meta) self.assertEqual(new_image['location_data'][1]['url'], location % 2) self.assertEqual(new_image['location_data'][1]['metadata'], {}) self.client.metadata_encryption_key = None def test_add_image_already_exists(self): """Tests proper exception is raised if image with ID already exists""" fixture = self.get_fixture(id=UUID2, location="file:///tmp/glance-tests/2") self.assertRaises(exception.Duplicate, self.client.add_image, fixture) def test_add_image_with_bad_status(self): """Tests proper exception is raised if a bad status is set""" fixture = self.get_fixture(status='bad status', location="file:///tmp/glance-tests/2") self.assertRaises(exception.Invalid, self.client.add_image, fixture) def test_update_image(self): """Tests that the /images PUT registry API updates the image""" fixture = {'name': 'fake public image #2', 'disk_format': 'vmdk'} self.assertTrue(self.client.update_image(UUID2, fixture)) # Test all other attributes set data = self.client.get_image(UUID2) for k, v in fixture.items(): self.assertEqual(v, data[k]) def test_update_image_not_existing(self): """Tests non existing image update doesn't work""" fixture = self.get_fixture(status='bad status') self.assertRaises(exception.NotFound, self.client.update_image, _gen_uuid(), fixture) def test_delete_image(self): """Tests that image metadata is deleted properly""" # Grab the original number of images orig_num_images = len(self.client.get_images()) # Delete image #2 image = self.FIXTURES[1] deleted_image = self.client.delete_image(image['id']) self.assertTrue(deleted_image) self.assertEqual(image['id'], deleted_image['id']) self.assertTrue(deleted_image['deleted']) self.assertTrue(deleted_image['deleted_at']) # Verify one less image new_num_images = len(self.client.get_images()) self.assertEqual(new_num_images, orig_num_images - 1) def test_delete_image_not_existing(self): """Check that one cannot delete non-existing image.""" self.assertRaises(exception.NotFound, self.client.delete_image, _gen_uuid()) def test_get_image_members(self): """Test getting image members.""" memb_list = self.client.get_image_members(UUID2) num_members = len(memb_list) self.assertEqual(num_members, 0) def test_get_image_members_not_existing(self): """Test getting non-existent image members.""" self.assertRaises(exception.NotFound, self.client.get_image_members, _gen_uuid()) def test_get_member_images(self): """Test getting member images.""" memb_list = self.client.get_member_images('pattieblack') num_members = len(memb_list) self.assertEqual(num_members, 0) def test_add_replace_members(self): """Test replacing image members.""" self.assertTrue(self.client.add_member(UUID2, 'pattieblack')) self.assertTrue(self.client.replace_members(UUID2, dict(member_id='pattie' 'black2'))) def test_add_delete_member(self): """Tests deleting image members""" self.client.add_member(UUID2, 'pattieblack') self.assertTrue(self.client.delete_member(UUID2, 'pattieblack')) class TestBaseClient(testtools.TestCase): """ Test proper actions made for both valid and invalid requests against a Registry service """ def test_connect_kwargs_default_values(self): actual = test_client.BaseClient('127.0.0.1').get_connect_kwargs() self.assertEqual({'timeout': None}, actual) def test_connect_kwargs(self): base_client = test_client.BaseClient( host='127.0.0.1', port=80, timeout=1, use_ssl=True) actual = base_client.get_connect_kwargs() expected = {'insecure': False, 'key_file': None, 'cert_file': None, 'timeout': 1} for k in expected.keys(): self.assertEqual(expected[k], actual[k]) class TestRegistryV1ClientApi(base.IsolatedUnitTest): def setUp(self): """Establish a clean test environment.""" super(TestRegistryV1ClientApi, self).setUp() self.mox = mox.Mox() self.context = context.RequestContext() reload(rapi) def tearDown(self): """Clear the test environment.""" super(TestRegistryV1ClientApi, self).tearDown() self.mox.UnsetStubs() def test_get_registry_client(self): actual_client = rapi.get_registry_client(self.context) self.assertIsNone(actual_client.identity_headers) def test_get_registry_client_with_identity_headers(self): self.config(send_identity_headers=True) expected_identity_headers = { 'X-User-Id': self.context.user, 'X-Tenant-Id': self.context.tenant, 'X-Roles': ','.join(self.context.roles), 'X-Identity-Status': 'Confirmed', 'X-Service-Catalog': 'null', } actual_client = rapi.get_registry_client(self.context) self.assertEqual(actual_client.identity_headers, expected_identity_headers) def test_configure_registry_client_not_using_use_user_token(self): self.config(use_user_token=False) self.mox.StubOutWithMock(rapi, 'configure_registry_admin_creds') rapi.configure_registry_admin_creds() self.mox.ReplayAll() rapi.configure_registry_client() self.mox.VerifyAll() def _get_fake_config_creds(self, auth_url='auth_url', strategy='keystone'): return { 'user': 'user', 'password': 'password', 'username': 'user', 'tenant': 'tenant', 'auth_url': auth_url, 'strategy': strategy, 'region': 'region' } def test_configure_registry_admin_creds(self): expected = self._get_fake_config_creds(auth_url=None, strategy='configured_strategy') self.config(admin_user=expected['user']) self.config(admin_password=expected['password']) self.config(admin_tenant_name=expected['tenant']) self.config(auth_strategy=expected['strategy']) self.config(auth_region=expected['region']) self.stubs.Set(os, 'getenv', lambda x: None) self.assertIsNone(rapi._CLIENT_CREDS) rapi.configure_registry_admin_creds() self.assertEqual(rapi._CLIENT_CREDS, expected) def test_configure_registry_admin_creds_with_auth_url(self): expected = self._get_fake_config_creds() self.config(admin_user=expected['user']) self.config(admin_password=expected['password']) self.config(admin_tenant_name=expected['tenant']) self.config(auth_url=expected['auth_url']) self.config(auth_strategy='test_strategy') self.config(auth_region=expected['region']) self.assertIsNone(rapi._CLIENT_CREDS) rapi.configure_registry_admin_creds() self.assertEqual(rapi._CLIENT_CREDS, expected) class FakeResponse(): status = 202 def getheader(*args, **kwargs): return None class TestRegistryV1ClientRequests(base.IsolatedUnitTest): def setUp(self): super(TestRegistryV1ClientRequests, self).setUp() self.mox = mox.Mox() def tearDown(self): super(TestRegistryV1ClientRequests, self).tearDown() self.mox.UnsetStubs() def test_do_request_with_identity_headers(self): identity_headers = {'foo': 'bar'} self.client = rclient.RegistryClient("0.0.0.0", identity_headers=identity_headers) self.mox.StubOutWithMock(test_client.BaseClient, 'do_request') test_client.BaseClient.do_request( "GET", "/images", headers=identity_headers).AndReturn(FakeResponse()) self.mox.ReplayAll() self.client.do_request("GET", "/images") self.mox.VerifyAll() def test_do_request(self): self.client = rclient.RegistryClient("0.0.0.0") self.mox.StubOutWithMock(test_client.BaseClient, 'do_request') test_client.BaseClient.do_request("GET", "/images", headers={}).AndReturn(FakeResponse()) self.mox.ReplayAll() self.client.do_request("GET", "/images") self.mox.VerifyAll() glance-2014.1/glance/tests/unit/v1/test_registry_api.py0000664000175400017540000023501012323736226024211 0ustar jenkinsjenkins00000000000000# -*- coding: utf-8 -*- # Copyright 2010-2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import datetime import uuid from oslo.config import cfg import routes import webob import glance.api.common import glance.common.config from glance.common import crypt from glance import context from glance.db.sqlalchemy import api as db_api from glance.db.sqlalchemy import models as db_models from glance.openstack.common import jsonutils from glance.openstack.common import timeutils from glance.registry.api import v1 as rserver import glance.store.filesystem from glance.tests.unit import base from glance.tests import utils as test_utils CONF = cfg.CONF _gen_uuid = lambda: str(uuid.uuid4()) UUID1 = _gen_uuid() UUID2 = _gen_uuid() class TestRegistryAPI(base.IsolatedUnitTest, test_utils.RegistryAPIMixIn): def setUp(self): """Establish a clean test environment""" super(TestRegistryAPI, self).setUp() self.mapper = routes.Mapper() self.api = test_utils.FakeAuthMiddleware(rserver.API(self.mapper), is_admin=True) def _get_extra_fixture(id, name, **kwargs): return self.get_extra_fixture( id, name, locations=[{'url': "file:///%s/%s" % (self.test_dir, id), 'metadata': {}}], **kwargs) self.FIXTURES = [ _get_extra_fixture(UUID1, 'fake image #1', is_public=False, disk_format='ami', container_format='ami', min_disk=0, min_ram=0, owner=123, size=13, properties={'type': 'kernel'}), _get_extra_fixture(UUID2, 'fake image #2', min_disk=5, min_ram=256, size=19, properties={})] self.context = context.RequestContext(is_admin=True) db_api.get_engine() self.destroy_fixtures() self.create_fixtures() def tearDown(self): """Clear the test environment""" super(TestRegistryAPI, self).tearDown() self.destroy_fixtures() def test_show(self): """ Tests that the /images/ registry API endpoint returns the expected image """ fixture = {'id': UUID2, 'name': 'fake image #2', 'size': 19, 'min_ram': 256, 'min_disk': 5, 'checksum': None} res = self.get_api_response_ext(200, '/images/%s' % UUID2) res_dict = jsonutils.loads(res.body) image = res_dict['image'] for k, v in fixture.iteritems(): self.assertEqual(v, image[k]) def test_show_unknown(self): """ Tests that the /images/ registry API endpoint returns a 404 for an unknown image id """ self.get_api_response_ext(404, '/images/%s' % _gen_uuid()) def test_show_invalid(self): """ Tests that the /images/ registry API endpoint returns a 404 for an invalid (therefore unknown) image id """ self.get_api_response_ext(404, '/images/%s' % _gen_uuid()) def test_show_deleted_image_as_admin(self): """ Tests that the /images/ registry API endpoint returns a 200 for deleted image to admin user. """ # Delete image #2 self.get_api_response_ext(200, '/images/%s' % UUID2, method='DELETE') self.get_api_response_ext(200, '/images/%s' % UUID2) def test_show_deleted_image_as_nonadmin(self): """ Tests that the /images/ registry API endpoint returns a 404 for deleted image to non-admin user. """ # Delete image #2 self.get_api_response_ext(200, '/images/%s' % UUID2, method='DELETE') api = test_utils.FakeAuthMiddleware(rserver.API(self.mapper), is_admin=False) self.get_api_response_ext(404, '/images/%s' % UUID2, api=api) def test_show_private_image_with_no_admin_user(self): UUID4 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID4, size=18, owner='test user', is_public=False) db_api.image_create(self.context, extra_fixture) test_rserv = rserver.API(self.mapper) api = test_utils.FakeAuthMiddleware(test_rserv, is_admin=False) self.get_api_response_ext(404, '/images/%s' % UUID4, api=api) def test_get_root(self): """ Tests that the root registry API returns "index", which is a list of public images """ fixture = {'id': UUID2, 'size': 19, 'checksum': None} res = self.get_api_response_ext(200, url='/') res_dict = jsonutils.loads(res.body) images = res_dict['images'] self.assertEqual(len(images), 1) for k, v in fixture.iteritems(): self.assertEqual(v, images[0][k]) def test_get_index(self): """ Tests that the /images registry API returns list of public images """ fixture = {'id': UUID2, 'size': 19, 'checksum': None} res = self.get_api_response_ext(200) res_dict = jsonutils.loads(res.body) images = res_dict['images'] self.assertEqual(len(images), 1) for k, v in fixture.iteritems(): self.assertEqual(v, images[0][k]) def test_get_index_marker(self): """ Tests that the /images registry API returns list of public images that conforms to a marker query param """ time1 = timeutils.utcnow() + datetime.timedelta(seconds=5) time2 = timeutils.utcnow() + datetime.timedelta(seconds=4) time3 = timeutils.utcnow() UUID3 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID3, size=19, created_at=time1) db_api.image_create(self.context, extra_fixture) UUID4 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID4, created_at=time2) db_api.image_create(self.context, extra_fixture) UUID5 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID5, created_at=time3) db_api.image_create(self.context, extra_fixture) res = self.get_api_response_ext(200, url='/images?marker=%s' % UUID4) self.assertEqualImages(res, (UUID5, UUID2)) def test_get_index_unknown_marker(self): """ Tests that the /images registry API returns a 400 when an unknown marker is provided """ self.get_api_response_ext(400, url='/images?marker=%s' % _gen_uuid()) def test_get_index_malformed_marker(self): """ Tests that the /images registry API returns a 400 when a malformed marker is provided """ res = self.get_api_response_ext(400, url='/images?marker=4') self.assertTrue('marker' in res.body) def test_get_index_forbidden_marker(self): """ Tests that the /images registry API returns a 400 when a forbidden marker is provided """ test_rserv = rserver.API(self.mapper) api = test_utils.FakeAuthMiddleware(test_rserv, is_admin=False) self.get_api_response_ext(400, url='/images?marker=%s' % UUID1, api=api) def test_get_index_limit(self): """ Tests that the /images registry API returns list of public images that conforms to a limit query param """ UUID3 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID3, size=19) db_api.image_create(self.context, extra_fixture) UUID4 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID4) db_api.image_create(self.context, extra_fixture) res = self.get_api_response_ext(200, url='/images?limit=1') res_dict = jsonutils.loads(res.body) images = res_dict['images'] self.assertEqual(len(images), 1) # expect list to be sorted by created_at desc self.assertEqual(images[0]['id'], UUID4) def test_get_index_limit_negative(self): """ Tests that the /images registry API returns list of public images that conforms to a limit query param """ self.get_api_response_ext(400, url='/images?limit=-1') def test_get_index_limit_non_int(self): """ Tests that the /images registry API returns list of public images that conforms to a limit query param """ self.get_api_response_ext(400, url='/images?limit=a') def test_get_index_limit_marker(self): """ Tests that the /images registry API returns list of public images that conforms to limit and marker query params """ UUID3 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID3, size=19) db_api.image_create(self.context, extra_fixture) extra_fixture = self.get_fixture(id=_gen_uuid()) db_api.image_create(self.context, extra_fixture) res = self.get_api_response_ext( 200, url='/images?marker=%s&limit=1' % UUID3) self.assertEqualImages(res, (UUID2,)) def test_get_index_filter_on_user_defined_properties(self): """ Tests that /images registry API returns list of public images based a filter on user-defined properties. """ image1_id = _gen_uuid() properties = {'distro': 'ubuntu', 'arch': 'i386'} extra_fixture = self.get_fixture(id=image1_id, name='image-extra-1', properties=properties) db_api.image_create(self.context, extra_fixture) image2_id = _gen_uuid() properties = {'distro': 'ubuntu', 'arch': 'x86_64', 'foo': 'bar'} extra_fixture = self.get_fixture(id=image2_id, name='image-extra-2', properties=properties) db_api.image_create(self.context, extra_fixture) # Test index with filter containing one user-defined property. # Filter is 'property-distro=ubuntu'. # Verify both image1 and image2 are returned res = self.get_api_response_ext(200, url='/images?' 'property-distro=ubuntu') images = jsonutils.loads(res.body)['images'] self.assertEqual(len(images), 2) self.assertEqual(images[0]['id'], image2_id) self.assertEqual(images[1]['id'], image1_id) # Test index with filter containing one user-defined property but # non-existent value. Filter is 'property-distro=fedora'. # Verify neither images are returned res = self.get_api_response_ext(200, url='/images?' 'property-distro=fedora') images = jsonutils.loads(res.body)['images'] self.assertEqual(len(images), 0) # Test index with filter containing one user-defined property but # unique value. Filter is 'property-arch=i386'. # Verify only image1 is returned. res = self.get_api_response_ext(200, url='/images?' 'property-arch=i386') images = jsonutils.loads(res.body)['images'] self.assertEqual(len(images), 1) self.assertEqual(images[0]['id'], image1_id) # Test index with filter containing one user-defined property but # unique value. Filter is 'property-arch=x86_64'. # Verify only image1 is returned. res = self.get_api_response_ext(200, url='/images?' 'property-arch=x86_64') images = jsonutils.loads(res.body)['images'] self.assertEqual(len(images), 1) self.assertEqual(images[0]['id'], image2_id) # Test index with filter containing unique user-defined property. # Filter is 'property-foo=bar'. # Verify only image2 is returned. res = self.get_api_response_ext(200, url='/images?property-foo=bar') images = jsonutils.loads(res.body)['images'] self.assertEqual(len(images), 1) self.assertEqual(images[0]['id'], image2_id) # Test index with filter containing unique user-defined property but # .value is non-existent. Filter is 'property-foo=baz'. # Verify neither images are returned. res = self.get_api_response_ext(200, url='/images?property-foo=baz') images = jsonutils.loads(res.body)['images'] self.assertEqual(len(images), 0) # Test index with filter containing multiple user-defined properties # Filter is 'property-arch=x86_64&property-distro=ubuntu'. # Verify only image2 is returned. res = self.get_api_response_ext(200, url='/images?' 'property-arch=x86_64&' 'property-distro=ubuntu') images = jsonutils.loads(res.body)['images'] self.assertEqual(len(images), 1) self.assertEqual(images[0]['id'], image2_id) # Test index with filter containing multiple user-defined properties # Filter is 'property-arch=i386&property-distro=ubuntu'. # Verify only image1 is returned. res = self.get_api_response_ext(200, url='/images?property-arch=i386&' 'property-distro=ubuntu') images = jsonutils.loads(res.body)['images'] self.assertEqual(len(images), 1) self.assertEqual(images[0]['id'], image1_id) # Test index with filter containing multiple user-defined properties. # Filter is 'property-arch=random&property-distro=ubuntu'. # Verify neither images are returned. res = self.get_api_response_ext(200, url='/images?' 'property-arch=random&' 'property-distro=ubuntu') images = jsonutils.loads(res.body)['images'] self.assertEqual(len(images), 0) # Test index with filter containing multiple user-defined properties. # Filter is 'property-arch=random&property-distro=random'. # Verify neither images are returned. res = self.get_api_response_ext(200, url='/images?' 'property-arch=random&' 'property-distro=random') images = jsonutils.loads(res.body)['images'] self.assertEqual(len(images), 0) # Test index with filter containing multiple user-defined properties. # Filter is 'property-boo=far&property-poo=far'. # Verify neither images are returned. res = self.get_api_response_ext(200, url='/images?property-boo=far&' 'property-poo=far') images = jsonutils.loads(res.body)['images'] self.assertEqual(len(images), 0) # Test index with filter containing multiple user-defined properties. # Filter is 'property-foo=bar&property-poo=far'. # Verify neither images are returned. res = self.get_api_response_ext(200, url='/images?property-foo=bar&' 'property-poo=far') images = jsonutils.loads(res.body)['images'] self.assertEqual(len(images), 0) def test_get_index_filter_name(self): """ Tests that the /images registry API returns list of public images that have a specific name. This is really a sanity check, filtering is tested more in-depth using /images/detail """ extra_fixture = self.get_fixture(id=_gen_uuid(), name='new name! #123', size=19) db_api.image_create(self.context, extra_fixture) extra_fixture = self.get_fixture(id=_gen_uuid(), name='new name! #123') db_api.image_create(self.context, extra_fixture) res = self.get_api_response_ext(200, url='/images?name=new name! #123') res_dict = jsonutils.loads(res.body) images = res_dict['images'] self.assertEqual(len(images), 2) for image in images: self.assertEqual('new name! #123', image['name']) def test_get_index_sort_default_created_at_desc(self): """ Tests that the /images registry API returns list of public images that conforms to a default sort key/dir """ time1 = timeutils.utcnow() + datetime.timedelta(seconds=5) time2 = timeutils.utcnow() + datetime.timedelta(seconds=4) time3 = timeutils.utcnow() UUID3 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID3, size=19, created_at=time1) db_api.image_create(self.context, extra_fixture) UUID4 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID4, created_at=time2) db_api.image_create(self.context, extra_fixture) UUID5 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID5, created_at=time3) db_api.image_create(self.context, extra_fixture) res = self.get_api_response_ext(200, url='/images') self.assertEqualImages(res, (UUID3, UUID4, UUID5, UUID2)) def test_get_index_bad_sort_key(self): """Ensure a 400 is returned when a bad sort_key is provided.""" self.get_api_response_ext(400, url='/images?sort_key=asdf') def test_get_index_bad_sort_dir(self): """Ensure a 400 is returned when a bad sort_dir is provided.""" self.get_api_response_ext(400, url='/images?sort_dir=asdf') def test_get_index_null_name(self): """Check 200 is returned when sort_key is null name Check 200 is returned when sort_key is name and name is null for specified marker """ UUID6 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID6, name=None) db_api.image_create(self.context, extra_fixture) self.get_api_response_ext( 200, url='/images?sort_key=name&marker=%s' % UUID6) def test_get_index_null_disk_format(self): """Check 200 is returned when sort_key is null disk_format Check 200 is returned when sort_key is disk_format and disk_format is null for specified marker """ UUID6 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID6, disk_format=None, size=19) db_api.image_create(self.context, extra_fixture) self.get_api_response_ext( 200, url='/images?sort_key=disk_format&marker=%s' % UUID6) def test_get_index_null_container_format(self): """Check 200 is returned when sort_key is null container_format Check 200 is returned when sort_key is container_format and container_format is null for specified marker """ UUID6 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID6, container_format=None) db_api.image_create(self.context, extra_fixture) self.get_api_response_ext( 200, url='/images?sort_key=container_format&marker=%s' % UUID6) def test_get_index_sort_name_asc(self): """ Tests that the /images registry API returns list of public images sorted alphabetically by name in ascending order. """ UUID3 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID3, name='asdf', size=19) db_api.image_create(self.context, extra_fixture) UUID4 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID4, name='xyz') db_api.image_create(self.context, extra_fixture) url = '/images?sort_key=name&sort_dir=asc' res = self.get_api_response_ext(200, url=url) self.assertEqualImages(res, (UUID3, UUID2, UUID4)) def test_get_index_sort_status_desc(self): """ Tests that the /images registry API returns list of public images sorted alphabetically by status in descending order. """ UUID3 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID3, status='queued', size=19) db_api.image_create(self.context, extra_fixture) UUID4 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID4) db_api.image_create(self.context, extra_fixture) res = self.get_api_response_ext(200, url=( '/images?sort_key=status&sort_dir=desc')) self.assertEqualImages(res, (UUID3, UUID4, UUID2)) def test_get_index_sort_disk_format_asc(self): """ Tests that the /images registry API returns list of public images sorted alphabetically by disk_format in ascending order. """ UUID3 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID3, disk_format='ami', container_format='ami', size=19) db_api.image_create(self.context, extra_fixture) UUID4 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID4, disk_format='vdi') db_api.image_create(self.context, extra_fixture) res = self.get_api_response_ext(200, url=( '/images?sort_key=disk_format&sort_dir=asc')) self.assertEqualImages(res, (UUID3, UUID4, UUID2)) def test_get_index_sort_container_format_desc(self): """ Tests that the /images registry API returns list of public images sorted alphabetically by container_format in descending order. """ UUID3 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID3, size=19, disk_format='ami', container_format='ami') db_api.image_create(self.context, extra_fixture) UUID4 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID4, disk_format='iso', container_format='bare') db_api.image_create(self.context, extra_fixture) url = '/images?sort_key=container_format&sort_dir=desc' res = self.get_api_response_ext(200, url=url) self.assertEqualImages(res, (UUID2, UUID4, UUID3)) def test_get_index_sort_size_asc(self): """ Tests that the /images registry API returns list of public images sorted by size in ascending order. """ UUID3 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID3, disk_format='ami', container_format='ami', size=100) db_api.image_create(self.context, extra_fixture) UUID4 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID4, disk_format='iso', container_format='bare', size=2) db_api.image_create(self.context, extra_fixture) url = '/images?sort_key=size&sort_dir=asc' res = self.get_api_response_ext(200, url=url) self.assertEqualImages(res, (UUID4, UUID2, UUID3)) def test_get_index_sort_created_at_asc(self): """ Tests that the /images registry API returns list of public images sorted by created_at in ascending order. """ now = timeutils.utcnow() time1 = now + datetime.timedelta(seconds=5) time2 = now UUID3 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID3, created_at=time1, size=19) db_api.image_create(self.context, extra_fixture) UUID4 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID4, created_at=time2) db_api.image_create(self.context, extra_fixture) res = self.get_api_response_ext(200, url=( '/images?sort_key=created_at&sort_dir=asc')) self.assertEqualImages(res, (UUID2, UUID4, UUID3)) def test_get_index_sort_updated_at_desc(self): """ Tests that the /images registry API returns list of public images sorted by updated_at in descending order. """ now = timeutils.utcnow() time1 = now + datetime.timedelta(seconds=5) time2 = now UUID3 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID3, size=19, created_at=None, updated_at=time1) db_api.image_create(self.context, extra_fixture) UUID4 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID4, created_at=None, updated_at=time2) db_api.image_create(self.context, extra_fixture) res = self.get_api_response_ext(200, url=( '/images?sort_key=updated_at&sort_dir=desc')) self.assertEqualImages(res, (UUID3, UUID4, UUID2)) def test_get_details(self): """ Tests that the /images/detail registry API returns a mapping containing a list of detailed image information """ fixture = {'id': UUID2, 'name': 'fake image #2', 'is_public': True, 'size': 19, 'min_disk': 5, 'min_ram': 256, 'checksum': None, 'disk_format': 'vhd', 'container_format': 'ovf', 'status': 'active'} res = self.get_api_response_ext(200, url='/images/detail') res_dict = jsonutils.loads(res.body) images = res_dict['images'] self.assertEqual(len(images), 1) for k, v in fixture.iteritems(): self.assertEqual(v, images[0][k]) def test_get_details_limit_marker(self): """ Tests that the /images/details registry API returns list of public images that conforms to limit and marker query params. This functionality is tested more thoroughly on /images, this is just a sanity check """ UUID3 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID3, size=20) db_api.image_create(self.context, extra_fixture) extra_fixture = self.get_fixture(id=_gen_uuid()) db_api.image_create(self.context, extra_fixture) url = '/images/detail?marker=%s&limit=1' % UUID3 res = self.get_api_response_ext(200, url=url) res_dict = jsonutils.loads(res.body) images = res_dict['images'] self.assertEqual(len(images), 1) # expect list to be sorted by created_at desc self.assertEqual(images[0]['id'], UUID2) def test_get_details_invalid_marker(self): """ Tests that the /images/detail registry API returns a 400 when an invalid marker is provided """ url = '/images/detail?marker=%s' % _gen_uuid() self.get_api_response_ext(400, url=url) def test_get_details_malformed_marker(self): """ Tests that the /images/detail registry API returns a 400 when a malformed marker is provided """ res = self.get_api_response_ext(400, url='/images/detail?marker=4') self.assertTrue('marker' in res.body) def test_get_details_forbidden_marker(self): """ Tests that the /images/detail registry API returns a 400 when a forbidden marker is provided """ test_rserv = rserver.API(self.mapper) api = test_utils.FakeAuthMiddleware(test_rserv, is_admin=False) self.get_api_response_ext(400, api=api, url='/images/detail?marker=%s' % UUID1) def test_get_details_filter_name(self): """ Tests that the /images/detail registry API returns list of public images that have a specific name """ extra_fixture = self.get_fixture(id=_gen_uuid(), name='new name! #123', size=20) db_api.image_create(self.context, extra_fixture) extra_fixture = self.get_fixture(id=_gen_uuid(), name='new name! #123') db_api.image_create(self.context, extra_fixture) url = '/images/detail?name=new name! #123' res = self.get_api_response_ext(200, url=url) res_dict = jsonutils.loads(res.body) images = res_dict['images'] self.assertEqual(len(images), 2) for image in images: self.assertEqual('new name! #123', image['name']) def test_get_details_filter_status(self): """ Tests that the /images/detail registry API returns list of public images that have a specific status """ extra_fixture = self.get_fixture(id=_gen_uuid(), status='saving') db_api.image_create(self.context, extra_fixture) extra_fixture = self.get_fixture(id=_gen_uuid(), size=19, status='active') db_api.image_create(self.context, extra_fixture) res = self.get_api_response_ext(200, url='/images/detail?status=saving') res_dict = jsonutils.loads(res.body) images = res_dict['images'] self.assertEqual(len(images), 1) for image in images: self.assertEqual('saving', image['status']) def test_get_details_filter_container_format(self): """ Tests that the /images/detail registry API returns list of public images that have a specific container_format """ extra_fixture = self.get_fixture(id=_gen_uuid(), disk_format='vdi', size=19) db_api.image_create(self.context, extra_fixture) extra_fixture = self.get_fixture(id=_gen_uuid(), disk_format='ami', container_format='ami', size=19) db_api.image_create(self.context, extra_fixture) url = '/images/detail?container_format=ovf' res = self.get_api_response_ext(200, url=url) res_dict = jsonutils.loads(res.body) images = res_dict['images'] self.assertEqual(len(images), 2) for image in images: self.assertEqual('ovf', image['container_format']) def test_get_details_filter_min_disk(self): """ Tests that the /images/detail registry API returns list of public images that have a specific min_disk """ extra_fixture = self.get_fixture(id=_gen_uuid(), min_disk=7, size=19) db_api.image_create(self.context, extra_fixture) extra_fixture = self.get_fixture(id=_gen_uuid(), disk_format='ami', container_format='ami', size=19) db_api.image_create(self.context, extra_fixture) res = self.get_api_response_ext(200, url='/images/detail?min_disk=7') res_dict = jsonutils.loads(res.body) images = res_dict['images'] self.assertEqual(len(images), 1) for image in images: self.assertEqual(7, image['min_disk']) def test_get_details_filter_min_ram(self): """ Tests that the /images/detail registry API returns list of public images that have a specific min_ram """ extra_fixture = self.get_fixture(id=_gen_uuid(), min_ram=514, size=19) db_api.image_create(self.context, extra_fixture) extra_fixture = self.get_fixture(id=_gen_uuid(), disk_format='ami', container_format='ami', size=19) db_api.image_create(self.context, extra_fixture) res = self.get_api_response_ext(200, url='/images/detail?min_ram=514') res_dict = jsonutils.loads(res.body) images = res_dict['images'] self.assertEqual(len(images), 1) for image in images: self.assertEqual(514, image['min_ram']) def test_get_details_filter_disk_format(self): """ Tests that the /images/detail registry API returns list of public images that have a specific disk_format """ extra_fixture = self.get_fixture(id=_gen_uuid(), size=19) db_api.image_create(self.context, extra_fixture) extra_fixture = self.get_fixture(id=_gen_uuid(), disk_format='ami', container_format='ami', size=19) db_api.image_create(self.context, extra_fixture) res = self.get_api_response_ext(200, url='/images/detail?disk_format=vhd') res_dict = jsonutils.loads(res.body) images = res_dict['images'] self.assertEqual(len(images), 2) for image in images: self.assertEqual('vhd', image['disk_format']) def test_get_details_filter_size_min(self): """ Tests that the /images/detail registry API returns list of public images that have a size greater than or equal to size_min """ extra_fixture = self.get_fixture(id=_gen_uuid(), size=18) db_api.image_create(self.context, extra_fixture) extra_fixture = self.get_fixture(id=_gen_uuid(), disk_format='ami', container_format='ami') db_api.image_create(self.context, extra_fixture) res = self.get_api_response_ext(200, url='/images/detail?size_min=19') res_dict = jsonutils.loads(res.body) images = res_dict['images'] self.assertEqual(len(images), 2) for image in images: self.assertTrue(image['size'] >= 19) def test_get_details_filter_size_max(self): """ Tests that the /images/detail registry API returns list of public images that have a size less than or equal to size_max """ extra_fixture = self.get_fixture(id=_gen_uuid(), size=18) db_api.image_create(self.context, extra_fixture) extra_fixture = self.get_fixture(id=_gen_uuid(), disk_format='ami', container_format='ami') db_api.image_create(self.context, extra_fixture) res = self.get_api_response_ext(200, url='/images/detail?size_max=19') res_dict = jsonutils.loads(res.body) images = res_dict['images'] self.assertEqual(len(images), 2) for image in images: self.assertTrue(image['size'] <= 19) def test_get_details_filter_size_min_max(self): """ Tests that the /images/detail registry API returns list of public images that have a size less than or equal to size_max and greater than or equal to size_min """ extra_fixture = self.get_fixture(id=_gen_uuid(), size=18) db_api.image_create(self.context, extra_fixture) extra_fixture = self.get_fixture(id=_gen_uuid(), disk_format='ami', container_format='ami') db_api.image_create(self.context, extra_fixture) extra_fixture = self.get_fixture(id=_gen_uuid(), size=6) db_api.image_create(self.context, extra_fixture) url = '/images/detail?size_min=18&size_max=19' res = self.get_api_response_ext(200, url=url) res_dict = jsonutils.loads(res.body) images = res_dict['images'] self.assertEqual(len(images), 2) for image in images: self.assertTrue(image['size'] <= 19 and image['size'] >= 18) def test_get_details_filter_changes_since(self): """ Tests that the /images/detail registry API returns list of public images that have a size less than or equal to size_max """ dt1 = timeutils.utcnow() - datetime.timedelta(1) iso1 = timeutils.isotime(dt1) date_only1 = dt1.strftime('%Y-%m-%d') date_only2 = dt1.strftime('%Y%m%d') date_only3 = dt1.strftime('%Y-%m%d') dt2 = timeutils.utcnow() + datetime.timedelta(1) iso2 = timeutils.isotime(dt2) image_ts = timeutils.utcnow() + datetime.timedelta(2) hour_before = image_ts.strftime('%Y-%m-%dT%H:%M:%S%%2B01:00') hour_after = image_ts.strftime('%Y-%m-%dT%H:%M:%S-01:00') dt4 = timeutils.utcnow() + datetime.timedelta(3) iso4 = timeutils.isotime(dt4) UUID3 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID3, size=18) db_api.image_create(self.context, extra_fixture) db_api.image_destroy(self.context, UUID3) UUID4 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID4, disk_format='ami', container_format='ami', created_at=image_ts, updated_at=image_ts) db_api.image_create(self.context, extra_fixture) # Check a standard list, 4 images in db (2 deleted) res = self.get_api_response_ext(200, url='/images/detail') self.assertEqualImages(res, (UUID4, UUID2)) # Expect 3 images (1 deleted) res = self.get_api_response_ext(200, url=( '/images/detail?changes-since=%s' % iso1)) self.assertEqualImages(res, (UUID4, UUID3, UUID2)) # Expect 1 images (0 deleted) res = self.get_api_response_ext(200, url=( '/images/detail?changes-since=%s' % iso2)) self.assertEqualImages(res, (UUID4,)) # Expect 1 images (0 deleted) res = self.get_api_response_ext(200, url=( '/images/detail?changes-since=%s' % hour_before)) self.assertEqualImages(res, (UUID4,)) # Expect 0 images (0 deleted) res = self.get_api_response_ext(200, url=( '/images/detail?changes-since=%s' % hour_after)) self.assertEqualImages(res, ()) # Expect 0 images (0 deleted) res = self.get_api_response_ext(200, url=( '/images/detail?changes-since=%s' % iso4)) self.assertEqualImages(res, ()) for param in [date_only1, date_only2, date_only3]: # Expect 3 images (1 deleted) res = self.get_api_response_ext(200, url=( '/images/detail?changes-since=%s' % param)) self.assertEqualImages(res, (UUID4, UUID3, UUID2)) # Bad request (empty changes-since param) self.get_api_response_ext(400, url='/images/detail?changes-since=') def test_get_details_filter_property(self): """ Tests that the /images/detail registry API returns list of public images that have a specific custom property """ extra_fixture = self.get_fixture(id=_gen_uuid(), size=19, properties={'prop_123': 'v a'}) db_api.image_create(self.context, extra_fixture) extra_fixture = self.get_fixture(id=_gen_uuid(), size=19, disk_format='ami', container_format='ami', properties={'prop_123': 'v b'}) db_api.image_create(self.context, extra_fixture) res = self.get_api_response_ext(200, url=( '/images/detail?property-prop_123=v%20a')) res_dict = jsonutils.loads(res.body) images = res_dict['images'] self.assertEqual(len(images), 1) for image in images: self.assertEqual('v a', image['properties']['prop_123']) def test_get_details_filter_public_none(self): """ Tests that the /images/detail registry API returns list of all images if is_public none is passed """ extra_fixture = self.get_fixture(id=_gen_uuid(), is_public=False, size=18) db_api.image_create(self.context, extra_fixture) res = self.get_api_response_ext(200, url='/images/detail?is_public=None') res_dict = jsonutils.loads(res.body) images = res_dict['images'] self.assertEqual(len(images), 3) def test_get_details_filter_public_false(self): """ Tests that the /images/detail registry API returns list of private images if is_public false is passed """ extra_fixture = self.get_fixture(id=_gen_uuid(), is_public=False, size=18) db_api.image_create(self.context, extra_fixture) res = self.get_api_response_ext(200, url='/images/detail?is_public=False') res_dict = jsonutils.loads(res.body) images = res_dict['images'] self.assertEqual(len(images), 2) for image in images: self.assertEqual(False, image['is_public']) def test_get_details_filter_public_true(self): """ Tests that the /images/detail registry API returns list of public images if is_public true is passed (same as default) """ extra_fixture = self.get_fixture(id=_gen_uuid(), is_public=False, size=18) db_api.image_create(self.context, extra_fixture) res = self.get_api_response_ext(200, url='/images/detail?is_public=True') res_dict = jsonutils.loads(res.body) images = res_dict['images'] self.assertEqual(len(images), 1) for image in images: self.assertTrue(image['is_public']) def test_get_details_filter_public_string_format(self): """ Tests that the /images/detail registry API returns 400 Bad error for filter is_public with wrong format """ extra_fixture = self.get_fixture(id=_gen_uuid(), is_public='true', size=18) db_api.image_create(self.context, extra_fixture) self.get_api_response_ext(400, url='/images/detail?is_public=public') def test_get_details_filter_deleted_false(self): """ Test that the /images/detail registry API return list of images with deleted filter = false """ extra_fixture = {'id': _gen_uuid(), 'status': 'active', 'disk_format': 'vhd', 'container_format': 'ovf', 'name': 'test deleted filter 1', 'size': 18, 'deleted': False, 'checksum': None} db_api.image_create(self.context, extra_fixture) res = self.get_api_response_ext(200, url='/images/detail?deleted=False') res_dict = jsonutils.loads(res.body) images = res_dict['images'] for image in images: self.assertEqual(False, image['deleted']) def test_get_filter_no_public_with_no_admin(self): """ Tests that the /images/detail registry API returns list of public images if is_public true is passed (same as default) """ UUID4 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID4, is_public=False, size=18) db_api.image_create(self.context, extra_fixture) test_rserv = rserver.API(self.mapper) api = test_utils.FakeAuthMiddleware(test_rserv, is_admin=False) res = self.get_api_response_ext(200, api=api, url='/images/detail?is_public=False') res_dict = jsonutils.loads(res.body) images = res_dict['images'] self.assertEqual(len(images), 1) # Check that for non admin user only is_public = True images returns for image in images: self.assertTrue(image['is_public']) def test_get_filter_protected_with_None_value(self): """ Tests that the /images/detail registry API returns 400 error """ extra_fixture = self.get_fixture(id=_gen_uuid(), size=18, protected="False") db_api.image_create(self.context, extra_fixture) self.get_api_response_ext(400, url='/images/detail?protected=') def test_get_filter_protected_with_True_value(self): """ Tests that the /images/detail registry API returns 400 error """ extra_fixture = self.get_fixture(id=_gen_uuid(), size=18, protected="True") db_api.image_create(self.context, extra_fixture) self.get_api_response_ext(200, url='/images/detail?protected=True') def test_get_details_sort_name_asc(self): """ Tests that the /images/details registry API returns list of public images sorted alphabetically by name in ascending order. """ UUID3 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID3, name='asdf', size=19) db_api.image_create(self.context, extra_fixture) UUID4 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID4, name='xyz') db_api.image_create(self.context, extra_fixture) res = self.get_api_response_ext(200, url=( '/images/detail?sort_key=name&sort_dir=asc')) self.assertEqualImages(res, (UUID3, UUID2, UUID4)) def test_create_image(self): """Tests that the /images POST registry API creates the image""" fixture = self.get_minimal_fixture() body = jsonutils.dumps(dict(image=fixture)) res = self.get_api_response_ext(200, body=body, method='POST', content_type='json') res_dict = jsonutils.loads(res.body) for k, v in fixture.iteritems(): self.assertEqual(v, res_dict['image'][k]) # Test status was updated properly self.assertEqual('active', res_dict['image']['status']) def test_create_image_with_min_disk(self): """Tests that the /images POST registry API creates the image""" fixture = self.get_minimal_fixture(min_disk=5) body = jsonutils.dumps(dict(image=fixture)) res = self.get_api_response_ext(200, body=body, method='POST', content_type='json') res_dict = jsonutils.loads(res.body) self.assertEqual(5, res_dict['image']['min_disk']) def test_create_image_with_min_ram(self): """Tests that the /images POST registry API creates the image""" fixture = self.get_minimal_fixture(min_ram=256) body = jsonutils.dumps(dict(image=fixture)) res = self.get_api_response_ext(200, body=body, method='POST', content_type='json') res_dict = jsonutils.loads(res.body) self.assertEqual(256, res_dict['image']['min_ram']) def test_create_image_with_min_ram_default(self): """Tests that the /images POST registry API creates the image""" fixture = self.get_minimal_fixture() body = jsonutils.dumps(dict(image=fixture)) res = self.get_api_response_ext(200, body=body, method='POST', content_type='json') res_dict = jsonutils.loads(res.body) self.assertEqual(0, res_dict['image']['min_ram']) def test_create_image_with_min_disk_default(self): """Tests that the /images POST registry API creates the image""" fixture = self.get_minimal_fixture() body = jsonutils.dumps(dict(image=fixture)) res = self.get_api_response_ext(200, body=body, method='POST', content_type='json') res_dict = jsonutils.loads(res.body) self.assertEqual(0, res_dict['image']['min_disk']) def test_create_image_with_bad_status(self): """Tests proper exception is raised if a bad status is set""" fixture = self.get_minimal_fixture(id=_gen_uuid(), status='bad status') body = jsonutils.dumps(dict(image=fixture)) res = self.get_api_response_ext(400, body=body, method='POST', content_type='json') self.assertTrue('Invalid image status' in res.body) def test_create_image_with_bad_id(self): """Tests proper exception is raised if a bad disk_format is set""" fixture = self.get_minimal_fixture(id='asdf') self.get_api_response_ext(400, content_type='json', method='POST', body=jsonutils.dumps(dict(image=fixture))) def test_create_image_with_image_id_in_log(self): """Tests correct image id in log message when creating image""" fixture = self.get_minimal_fixture( id='0564c64c-3545-4e34-abfb-9d18e5f2f2f9') self.log_image_id = False def fake_log_info(msg): if 'Successfully created image ' \ '0564c64c-3545-4e34-abfb-9d18e5f2f2f9' in msg: self.log_image_id = True self.stubs.Set(rserver.images.LOG, 'info', fake_log_info) self.get_api_response_ext(200, content_type='json', method='POST', body=jsonutils.dumps(dict(image=fixture))) self.assertTrue(self.log_image_id) def test_update_image(self): """Tests that the /images PUT registry API updates the image""" fixture = {'name': 'fake public image #2', 'min_disk': 5, 'min_ram': 256, 'disk_format': 'raw'} body = jsonutils.dumps(dict(image=fixture)) res = self.get_api_response_ext(200, url='/images/%s' % UUID2, body=body, method='PUT', content_type='json') res_dict = jsonutils.loads(res.body) self.assertNotEqual(res_dict['image']['created_at'], res_dict['image']['updated_at']) for k, v in fixture.iteritems(): self.assertEqual(v, res_dict['image'][k]) def test_update_image_not_existing(self): """ Tests proper exception is raised if attempt to update non-existing image """ fixture = {'status': 'killed'} body = jsonutils.dumps(dict(image=fixture)) self.get_api_response_ext(404, url='/images/%s' % _gen_uuid(), method='PUT', body=body, content_type='json') def test_update_image_with_bad_status(self): """Tests that exception raised trying to set a bad status""" fixture = {'status': 'invalid'} body = jsonutils.dumps(dict(image=fixture)) res = self.get_api_response_ext(400, method='PUT', body=body, url='/images/%s' % UUID2, content_type='json') self.assertTrue('Invalid image status' in res.body) def test_update_private_image_no_admin(self): """ Tests proper exception is raised if attempt to update private image with non admin user, that not belongs to it """ UUID8 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID8, size=19, is_public=False, protected=True, owner='test user') db_api.image_create(self.context, extra_fixture) test_rserv = rserver.API(self.mapper) api = test_utils.FakeAuthMiddleware(test_rserv, is_admin=False) body = jsonutils.dumps(dict(image=extra_fixture)) self.get_api_response_ext(404, body=body, api=api, url='/images/%s' % UUID8, method='PUT', content_type='json') def test_delete_image(self): """Tests that the /images DELETE registry API deletes the image""" # Grab the original number of images res = self.get_api_response_ext(200) res_dict = jsonutils.loads(res.body) orig_num_images = len(res_dict['images']) # Delete image #2 self.get_api_response_ext(200, url='/images/%s' % UUID2, method='DELETE') # Verify one less image res = self.get_api_response_ext(200) res_dict = jsonutils.loads(res.body) new_num_images = len(res_dict['images']) self.assertEqual(new_num_images, orig_num_images - 1) def test_delete_image_response(self): """Tests that the registry API delete returns the image metadata""" image = self.FIXTURES[0] res = self.get_api_response_ext(200, url='/images/%s' % image['id'], method='DELETE') deleted_image = jsonutils.loads(res.body)['image'] self.assertEqual(image['id'], deleted_image['id']) self.assertTrue(deleted_image['deleted']) self.assertTrue(deleted_image['deleted_at']) def test_delete_image_not_existing(self): """ Tests proper exception is raised if attempt to delete non-existing image """ self.get_api_response_ext(404, url='/images/%s' % _gen_uuid(), method='DELETE') def test_delete_public_image_no_admin(self): """ Tests proper exception is raised if attempt to delete public image with non admin user """ UUID8 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID8, size=19, protected=True, owner='test user') db_api.image_create(self.context, extra_fixture) test_rserv = rserver.API(self.mapper) api = test_utils.FakeAuthMiddleware(test_rserv, is_admin=False) self.get_api_response_ext(403, url='/images/%s' % UUID8, method='DELETE', api=api) def test_delete_private_image_no_admin(self): """ Tests proper exception is raised if attempt to delete private image with non admin user, that not belongs to it """ UUID8 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID8, is_public=False, size=19, protected=True, owner='test user') db_api.image_create(self.context, extra_fixture) test_rserv = rserver.API(self.mapper) api = test_utils.FakeAuthMiddleware(test_rserv, is_admin=False) self.get_api_response_ext(404, url='/images/%s' % UUID8, method='DELETE', api=api) def test_get_image_members(self): """ Tests members listing for existing images """ res = self.get_api_response_ext(200, url='/images/%s/members' % UUID2, method='GET') memb_list = jsonutils.loads(res.body) num_members = len(memb_list['members']) self.assertEqual(num_members, 0) def test_get_image_members_not_existing(self): """ Tests proper exception is raised if attempt to get members of non-existing image """ self.get_api_response_ext(404, method='GET', url='/images/%s/members' % _gen_uuid()) def test_get_image_members_forbidden(self): """ Tests proper exception is raised if attempt to get members of non-existing image """ UUID8 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID8, is_public=False, size=19, protected=True, owner='test user') db_api.image_create(self.context, extra_fixture) test_rserv = rserver.API(self.mapper) api = test_utils.FakeAuthMiddleware(test_rserv, is_admin=False) self.get_api_response_ext(404, url='/images/%s/members' % UUID8, method='GET', api=api) def test_get_member_images(self): """ Tests image listing for members """ res = self.get_api_response_ext(200, url='/shared-images/pattieblack', method='GET') memb_list = jsonutils.loads(res.body) num_members = len(memb_list['shared_images']) self.assertEqual(num_members, 0) def test_replace_members(self): """ Tests replacing image members raises right exception """ self.api = test_utils.FakeAuthMiddleware(rserver.API(self.mapper), is_admin=False) fixture = dict(member_id='pattieblack') body = jsonutils.dumps(dict(image_memberships=fixture)) self.get_api_response_ext(401, method='PUT', body=body, url='/images/%s/members' % UUID2, content_type='json') def test_update_all_image_members_non_existing_image_id(self): """ Test update image members raises right exception """ # Update all image members fixture = dict(member_id='test1') req = webob.Request.blank('/images/%s/members' % _gen_uuid()) req.method = 'PUT' self.context.tenant = 'test2' req.content_type = 'application/json' req.body = jsonutils.dumps(dict(image_memberships=fixture)) res = req.get_response(self.api) self.assertEqual(res.status_int, 404) def test_update_all_image_members_invalid_membership_association(self): """ Test update image members raises right exception """ UUID8 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID8, size=19, protected=False, owner='test user') db_api.image_create(self.context, extra_fixture) # Add several members to image req = webob.Request.blank('/images/%s/members/test1' % UUID8) req.method = 'PUT' res = req.get_response(self.api) # Get all image members: res = self.get_api_response_ext(200, url='/images/%s/members' % UUID8, method='GET') memb_list = jsonutils.loads(res.body) num_members = len(memb_list['members']) self.assertEqual(num_members, 1) fixture = dict(member_id='test1') body = jsonutils.dumps(dict(image_memberships=fixture)) self.get_api_response_ext(400, url='/images/%s/members' % UUID8, method='PUT', body=body, content_type='json') def test_update_all_image_members_non_shared_image_forbidden(self): """ Test update image members raises right exception """ test_rserv = rserver.API(self.mapper) api = test_utils.FakeAuthMiddleware(test_rserv, is_admin=False) UUID9 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID9, size=19, protected=False) db_api.image_create(self.context, extra_fixture) fixture = dict(member_id='test1') req = webob.Request.blank('/images/%s/members' % UUID9) req.headers['X-Auth-Token'] = 'test1:test1:' req.method = 'PUT' req.content_type = 'application/json' req.body = jsonutils.dumps(dict(image_memberships=fixture)) res = req.get_response(api) self.assertEqual(res.status_int, 403) def test_update_all_image_members(self): """ Test update non existing image members """ UUID8 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID8, size=19, protected=False, owner='test user') db_api.image_create(self.context, extra_fixture) # Add several members to image req = webob.Request.blank('/images/%s/members/test1' % UUID8) req.method = 'PUT' req.get_response(self.api) fixture = [dict(member_id='test2', can_share=True)] body = jsonutils.dumps(dict(memberships=fixture)) self.get_api_response_ext(204, url='/images/%s/members' % UUID8, method='PUT', body=body, content_type='json') def test_update_all_image_members_bad_request(self): """ Test that right exception is raises in case if wrong memberships association is supplied """ UUID8 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID8, size=19, protected=False, owner='test user') db_api.image_create(self.context, extra_fixture) # Add several members to image req = webob.Request.blank('/images/%s/members/test1' % UUID8) req.method = 'PUT' req.get_response(self.api) fixture = dict(member_id='test3') body = jsonutils.dumps(dict(memberships=fixture)) self.get_api_response_ext(400, url='/images/%s/members' % UUID8, method='PUT', body=body, content_type='json') def test_update_all_image_existing_members(self): """ Test update existing image members """ UUID8 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID8, size=19, protected=False, owner='test user') db_api.image_create(self.context, extra_fixture) # Add several members to image req = webob.Request.blank('/images/%s/members/test1' % UUID8) req.method = 'PUT' req.get_response(self.api) fixture = [dict(member_id='test1', can_share=False)] body = jsonutils.dumps(dict(memberships=fixture)) self.get_api_response_ext(204, url='/images/%s/members' % UUID8, method='PUT', body=body, content_type='json') def test_add_member(self): """ Tests adding image members raises right exception """ self.api = test_utils.FakeAuthMiddleware(rserver.API(self.mapper), is_admin=False) self.get_api_response_ext(401, method='PUT', url=('/images/%s/members/pattieblack' % UUID2)) def test_add_member_to_image_positive(self): """ Test check that member can be successfully added """ UUID8 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID8, size=19, protected=False, owner='test user') db_api.image_create(self.context, extra_fixture) fixture = dict(can_share=True) test_uri = '/images/%s/members/test_add_member_positive' body = jsonutils.dumps(dict(member=fixture)) self.get_api_response_ext(204, url=test_uri % UUID8, method='PUT', body=body, content_type='json') def test_add_member_to_non_exist_image(self): """ Test check that member can't be added for non exist image """ fixture = dict(can_share=True) test_uri = '/images/%s/members/test_add_member_positive' body = jsonutils.dumps(dict(member=fixture)) self.get_api_response_ext(404, url=test_uri % _gen_uuid(), method='PUT', body=body, content_type='json') def test_add_image_member_non_shared_image_forbidden(self): """ Test update image members raises right exception """ test_rserver_api = rserver.API(self.mapper) api = test_utils.FakeAuthMiddleware( test_rserver_api, is_admin=False) UUID9 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID9, size=19, protected=False) db_api.image_create(self.context, extra_fixture) fixture = dict(can_share=True) test_uri = '/images/%s/members/test_add_member_to_non_share_image' req = webob.Request.blank(test_uri % UUID9) req.headers['X-Auth-Token'] = 'test1:test1:' req.method = 'PUT' req.content_type = 'application/json' req.body = jsonutils.dumps(dict(member=fixture)) res = req.get_response(api) self.assertEqual(res.status_int, 403) def test_add_member_to_image_bad_request(self): """ Test check right status code is returned """ UUID8 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID8, size=19, protected=False, owner='test user') db_api.image_create(self.context, extra_fixture) fixture = [dict(can_share=True)] test_uri = '/images/%s/members/test_add_member_bad_request' body = jsonutils.dumps(dict(member=fixture)) self.get_api_response_ext(400, url=test_uri % UUID8, method='PUT', body=body, content_type='json') def test_delete_member(self): """ Tests deleting image members raises right exception """ self.api = test_utils.FakeAuthMiddleware(rserver.API(self.mapper), is_admin=False) self.get_api_response_ext(401, method='DELETE', url=('/images/%s/members/pattieblack' % UUID2)) def test_delete_member_invalid(self): """ Tests deleting a invalid/non existing member raises right exception """ self.api = test_utils.FakeAuthMiddleware(rserver.API(self.mapper), is_admin=True) res = self.get_api_response_ext(404, method='DELETE', url=('/images/%s/members/pattieblack' % UUID2)) self.assertTrue('Membership could not be found' in res.body) def test_delete_member_from_non_exist_image(self): """ Tests deleting image members raises right exception """ test_rserver_api = rserver.API(self.mapper) self.api = test_utils.FakeAuthMiddleware( test_rserver_api, is_admin=True) test_uri = '/images/%s/members/pattieblack' self.get_api_response_ext(404, method='DELETE', url=test_uri % _gen_uuid()) def test_delete_image_member_non_shared_image_forbidden(self): """ Test delete image members raises right exception """ test_rserver_api = rserver.API(self.mapper) api = test_utils.FakeAuthMiddleware( test_rserver_api, is_admin=False) UUID9 = _gen_uuid() extra_fixture = self.get_fixture(id=UUID9, size=19, protected=False) db_api.image_create(self.context, extra_fixture) test_uri = '/images/%s/members/test_add_member_to_non_share_image' req = webob.Request.blank(test_uri % UUID9) req.headers['X-Auth-Token'] = 'test1:test1:' req.method = 'DELETE' req.content_type = 'application/json' res = req.get_response(api) self.assertEqual(res.status_int, 403) def test_get_images_bad_urls(self): """Check that routes collections are not on (LP bug 1185828)""" self.get_api_response_ext(404, url='/images/detail.xxx') self.get_api_response_ext(404, url='/images.xxx') self.get_api_response_ext(404, url='/images/new') self.get_api_response_ext(200, url='/images/%s/members' % UUID1) self.get_api_response_ext(404, url='/images/%s/members.xxx' % UUID1) class TestRegistryAPILocations(base.IsolatedUnitTest, test_utils.RegistryAPIMixIn): def setUp(self): """Establish a clean test environment""" super(TestRegistryAPILocations, self).setUp() self.mapper = routes.Mapper() self.api = test_utils.FakeAuthMiddleware(rserver.API(self.mapper), is_admin=True) def _get_extra_fixture(id, name, **kwargs): return self.get_extra_fixture( id, name, locations=[{'url': "file:///%s/%s" % (self.test_dir, id), 'metadata': {}}], **kwargs) self.FIXTURES = [ _get_extra_fixture(UUID1, 'fake image #1', is_public=False, disk_format='ami', container_format='ami', min_disk=0, min_ram=0, owner=123, size=13, properties={'type': 'kernel'}), _get_extra_fixture(UUID2, 'fake image #2', min_disk=5, min_ram=256, size=19, properties={})] self.context = context.RequestContext(is_admin=True) db_api.get_engine() self.destroy_fixtures() self.create_fixtures() def tearDown(self): """Clear the test environment""" super(TestRegistryAPILocations, self).tearDown() self.destroy_fixtures() def test_show_from_locations(self): req = webob.Request.blank('/images/%s' % UUID1) res = req.get_response(self.api) self.assertEqual(res.status_int, 200) res_dict = jsonutils.loads(res.body) image = res_dict['image'] self.assertEqual(self.FIXTURES[0]['locations'][0], image['location_data'][0]) self.assertEqual(self.FIXTURES[0]['locations'][0]['url'], image['location_data'][0]['url']) self.assertEqual(self.FIXTURES[0]['locations'][0]['metadata'], image['location_data'][0]['metadata']) def test_show_from_location_data(self): req = webob.Request.blank('/images/%s' % UUID2) res = req.get_response(self.api) self.assertEqual(res.status_int, 200) res_dict = jsonutils.loads(res.body) image = res_dict['image'] self.assertEqual(self.FIXTURES[1]['locations'][0], image['location_data'][0]) self.assertEqual(self.FIXTURES[1]['locations'][0]['url'], image['location_data'][0]['url']) self.assertEqual(self.FIXTURES[1]['locations'][0]['metadata'], image['location_data'][0]['metadata']) def test_create_from_location_data_with_encryption(self): encryption_key = '1234567890123456' location_url1 = "file:///%s/%s" % (self.test_dir, _gen_uuid()) location_url2 = "file:///%s/%s" % (self.test_dir, _gen_uuid()) encrypted_location_url1 = crypt.urlsafe_encrypt(encryption_key, location_url1, 64) encrypted_location_url2 = crypt.urlsafe_encrypt(encryption_key, location_url2, 64) fixture = {'name': 'fake image #3', 'status': 'active', 'disk_format': 'vhd', 'container_format': 'ovf', 'is_public': True, 'checksum': None, 'min_disk': 5, 'min_ram': 256, 'size': 19, 'location': encrypted_location_url1, 'location_data': [{'url': encrypted_location_url1, 'metadata': {'key': 'value'}}, {'url': encrypted_location_url2, 'metadata': {'key': 'value'}}]} self.config(metadata_encryption_key=encryption_key) req = webob.Request.blank('/images') req.method = 'POST' req.content_type = 'application/json' req.body = jsonutils.dumps(dict(image=fixture)) res = req.get_response(self.api) self.assertEqual(res.status_int, 200) res_dict = jsonutils.loads(res.body) image = res_dict['image'] # NOTE(zhiyan) _normalize_image_location_for_db() function will # not re-encrypted the url within location. self.assertEqual(fixture['location'], image['location']) self.assertEqual(len(image['location_data']), 2) self.assertEqual(fixture['location_data'][0]['url'], image['location_data'][0]['url']) self.assertEqual(fixture['location_data'][0]['metadata'], image['location_data'][0]['metadata']) self.assertEqual(fixture['location_data'][1]['url'], image['location_data'][1]['url']) self.assertEqual(fixture['location_data'][1]['metadata'], image['location_data'][1]['metadata']) image_entry = db_api.image_get(self.context, image['id']) self.assertEqual(image_entry['locations'][0]['url'], encrypted_location_url1) self.assertEqual(image_entry['locations'][1]['url'], encrypted_location_url2) decrypted_location_url1 = crypt.urlsafe_decrypt( encryption_key, image_entry['locations'][0]['url']) decrypted_location_url2 = crypt.urlsafe_decrypt( encryption_key, image_entry['locations'][1]['url']) self.assertEqual(location_url1, decrypted_location_url1) self.assertEqual(location_url2, decrypted_location_url2) class TestSharability(test_utils.BaseTestCase): def setUp(self): super(TestSharability, self).setUp() self.setup_db() self.controller = glance.registry.api.v1.members.Controller() def setup_db(self): db_api.get_engine() db_models.unregister_models(db_api.get_engine()) db_models.register_models(db_api.get_engine()) def test_is_image_sharable_as_admin(self): TENANT1 = str(uuid.uuid4()) TENANT2 = str(uuid.uuid4()) ctxt1 = context.RequestContext(is_admin=False, tenant=TENANT1, auth_tok='user:%s:user' % TENANT1, owner_is_tenant=True) ctxt2 = context.RequestContext(is_admin=True, user=TENANT2, auth_tok='user:%s:admin' % TENANT2, owner_is_tenant=False) UUIDX = str(uuid.uuid4()) #we need private image and context.owner should not match image owner image = db_api.image_create(ctxt1, {'id': UUIDX, 'status': 'queued', 'is_public': False, 'owner': TENANT1}) result = self.controller.is_image_sharable(ctxt2, image) self.assertTrue(result) def test_is_image_sharable_owner_can_share(self): TENANT1 = str(uuid.uuid4()) ctxt1 = context.RequestContext(is_admin=False, tenant=TENANT1, auth_tok='user:%s:user' % TENANT1, owner_is_tenant=True) UUIDX = str(uuid.uuid4()) #we need private image and context.owner should not match image owner image = db_api.image_create(ctxt1, {'id': UUIDX, 'status': 'queued', 'is_public': False, 'owner': TENANT1}) result = self.controller.is_image_sharable(ctxt1, image) self.assertTrue(result) def test_is_image_sharable_non_owner_cannot_share(self): TENANT1 = str(uuid.uuid4()) TENANT2 = str(uuid.uuid4()) ctxt1 = context.RequestContext(is_admin=False, tenant=TENANT1, auth_tok='user:%s:user' % TENANT1, owner_is_tenant=True) ctxt2 = context.RequestContext(is_admin=False, user=TENANT2, auth_tok='user:%s:user' % TENANT2, owner_is_tenant=False) UUIDX = str(uuid.uuid4()) #we need private image and context.owner should not match image owner image = db_api.image_create(ctxt1, {'id': UUIDX, 'status': 'queued', 'is_public': False, 'owner': TENANT1}) result = self.controller.is_image_sharable(ctxt2, image) self.assertFalse(result) def test_is_image_sharable_non_owner_can_share_as_image_member(self): TENANT1 = str(uuid.uuid4()) TENANT2 = str(uuid.uuid4()) ctxt1 = context.RequestContext(is_admin=False, tenant=TENANT1, auth_tok='user:%s:user' % TENANT1, owner_is_tenant=True) ctxt2 = context.RequestContext(is_admin=False, user=TENANT2, auth_tok='user:%s:user' % TENANT2, owner_is_tenant=False) UUIDX = str(uuid.uuid4()) #we need private image and context.owner should not match image owner image = db_api.image_create(ctxt1, {'id': UUIDX, 'status': 'queued', 'is_public': False, 'owner': TENANT1}) membership = {'can_share': True, 'member': TENANT2, 'image_id': UUIDX} db_api.image_member_create(ctxt1, membership) result = self.controller.is_image_sharable(ctxt2, image) self.assertTrue(result) def test_is_image_sharable_non_owner_as_image_member_without_sharing(self): TENANT1 = str(uuid.uuid4()) TENANT2 = str(uuid.uuid4()) ctxt1 = context.RequestContext(is_admin=False, tenant=TENANT1, auth_tok='user:%s:user' % TENANT1, owner_is_tenant=True) ctxt2 = context.RequestContext(is_admin=False, user=TENANT2, auth_tok='user:%s:user' % TENANT2, owner_is_tenant=False) UUIDX = str(uuid.uuid4()) #we need private image and context.owner should not match image owner image = db_api.image_create(ctxt1, {'id': UUIDX, 'status': 'queued', 'is_public': False, 'owner': TENANT1}) membership = {'can_share': False, 'member': TENANT2, 'image_id': UUIDX} db_api.image_member_create(ctxt1, membership) result = self.controller.is_image_sharable(ctxt2, image) self.assertFalse(result) def test_is_image_sharable_owner_is_none(self): TENANT1 = str(uuid.uuid4()) ctxt1 = context.RequestContext(is_admin=False, tenant=TENANT1, auth_tok='user:%s:user' % TENANT1, owner_is_tenant=True) ctxt2 = context.RequestContext(is_admin=False, tenant=None, auth_tok='user:%s:user' % TENANT1, owner_is_tenant=True) UUIDX = str(uuid.uuid4()) #we need private image and context.owner should not match image owner image = db_api.image_create(ctxt1, {'id': UUIDX, 'status': 'queued', 'is_public': False, 'owner': TENANT1}) result = self.controller.is_image_sharable(ctxt2, image) self.assertFalse(result) glance-2014.1/glance/tests/unit/v1/test_upload_utils.py0000664000175400017540000002750312323736226024222 0ustar jenkinsjenkins00000000000000# Copyright 2013 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import mox import webob.exc from glance.api.v1 import upload_utils from glance.common import exception import glance.registry.client.v1.api as registry import glance.store from glance.tests.unit import base import glance.tests.unit.utils as unit_test_utils class TestUploadUtils(base.StoreClearingUnitTest): def setUp(self): super(TestUploadUtils, self).setUp() self.config(verbose=True, debug=True) self.mox = mox.Mox() def tearDown(self): super(TestUploadUtils, self).tearDown() self.mox.UnsetStubs() def test_initiate_delete(self): req = unit_test_utils.get_fake_request() location = "file://foo/bar" id = unit_test_utils.UUID1 self.mox.StubOutWithMock(glance.store, "safe_delete_from_backend") glance.store.safe_delete_from_backend(req.context, location, id) self.mox.ReplayAll() upload_utils.initiate_deletion(req, location, id) self.mox.VerifyAll() def test_initiate_delete_with_delayed_delete(self): req = unit_test_utils.get_fake_request() location = "file://foo/bar" id = unit_test_utils.UUID1 self.mox.StubOutWithMock(glance.store, "schedule_delayed_delete_from_backend") glance.store.schedule_delayed_delete_from_backend(req.context, location, id) self.mox.ReplayAll() upload_utils.initiate_deletion(req, location, id, True) self.mox.VerifyAll() def test_safe_kill(self): req = unit_test_utils.get_fake_request() id = unit_test_utils.UUID1 self.mox.StubOutWithMock(registry, "update_image_metadata") registry.update_image_metadata(req.context, id, {'status': 'killed'}) self.mox.ReplayAll() upload_utils.safe_kill(req, id) self.mox.VerifyAll() def test_safe_kill_with_error(self): req = unit_test_utils.get_fake_request() id = unit_test_utils.UUID1 self.mox.StubOutWithMock(registry, "update_image_metadata") registry.update_image_metadata(req.context, id, {'status': 'killed'} ).AndRaise(Exception()) self.mox.ReplayAll() upload_utils.safe_kill(req, id) self.mox.VerifyAll() def test_upload_data_to_store(self): req = unit_test_utils.get_fake_request() location = "file://foo/bar" size = 10 checksum = "checksum" image_meta = {'id': unit_test_utils.UUID1, 'size': size} image_data = "blah" notifier = self.mox.CreateMockAnything() store = self.mox.CreateMockAnything() store.add( image_meta['id'], mox.IgnoreArg(), image_meta['size']).AndReturn((location, size, checksum, {})) self.mox.StubOutWithMock(registry, "update_image_metadata") update_data = {'checksum': checksum, 'size': size} registry.update_image_metadata( req.context, image_meta['id'], update_data).AndReturn(image_meta.update(update_data)) self.mox.ReplayAll() actual_meta, actual_loc, loc_meta = upload_utils.upload_data_to_store( req, image_meta, image_data, store, notifier) self.mox.VerifyAll() self.assertEqual(actual_loc, location) self.assertEqual(actual_meta, image_meta.update(update_data)) def test_upload_data_to_store_mismatch_size(self): req = unit_test_utils.get_fake_request() location = "file://foo/bar" size = 10 checksum = "checksum" image_meta = {'id': unit_test_utils.UUID1, 'size': size + 1} # Need incorrect size for test image_data = "blah" notifier = self.mox.CreateMockAnything() store = self.mox.CreateMockAnything() store.add( image_meta['id'], mox.IgnoreArg(), image_meta['size']).AndReturn((location, size, checksum, {})) self.mox.StubOutWithMock(registry, "update_image_metadata") update_data = {'checksum': checksum} registry.update_image_metadata( req.context, image_meta['id'], update_data).AndReturn(image_meta.update(update_data)) notifier.error('image.upload', mox.IgnoreArg()) self.mox.ReplayAll() self.assertRaises(webob.exc.HTTPBadRequest, upload_utils.upload_data_to_store, req, image_meta, image_data, store, notifier) self.mox.VerifyAll() def test_upload_data_to_store_mismatch_checksum(self): req = unit_test_utils.get_fake_request() location = "file://foo/bar" size = 10 checksum = "checksum" image_meta = {'id': unit_test_utils.UUID1, 'size': size} image_data = "blah" notifier = self.mox.CreateMockAnything() store = self.mox.CreateMockAnything() store.add( image_meta['id'], mox.IgnoreArg(), image_meta['size']).AndReturn((location, size, checksum + "NOT", {})) self.mox.StubOutWithMock(registry, "update_image_metadata") update_data = {'checksum': checksum} registry.update_image_metadata( req.context, image_meta['id'], update_data).AndReturn(image_meta.update(update_data)) notifier.error('image.upload', mox.IgnoreArg()) self.mox.ReplayAll() self.assertRaises(webob.exc.HTTPBadRequest, upload_utils.upload_data_to_store, req, image_meta, image_data, store, notifier) self.mox.VerifyAll() def _test_upload_data_to_store_exception(self, exc_class, expected_class): req = unit_test_utils.get_fake_request() size = 10 image_meta = {'id': unit_test_utils.UUID1, 'size': size} image_data = "blah" notifier = self.mox.CreateMockAnything() store = self.mox.CreateMockAnything() store.add( image_meta['id'], mox.IgnoreArg(), image_meta['size']).AndRaise(exc_class) self.mox.StubOutWithMock(upload_utils, "safe_kill") upload_utils.safe_kill(req, image_meta['id']) self.mox.ReplayAll() self.assertRaises(expected_class, upload_utils.upload_data_to_store, req, image_meta, image_data, store, notifier) self.mox.VerifyAll() def _test_upload_data_to_store_exception_with_notify(self, exc_class, expected_class, image_killed=True): req = unit_test_utils.get_fake_request() size = 10 image_meta = {'id': unit_test_utils.UUID1, 'size': size} image_data = "blah" store = self.mox.CreateMockAnything() store.add( image_meta['id'], mox.IgnoreArg(), image_meta['size']).AndRaise(exc_class) if image_killed: self.mox.StubOutWithMock(upload_utils, "safe_kill") upload_utils.safe_kill(req, image_meta['id']) notifier = self.mox.CreateMockAnything() notifier.error('image.upload', mox.IgnoreArg()) self.mox.ReplayAll() self.assertRaises(expected_class, upload_utils.upload_data_to_store, req, image_meta, image_data, store, notifier) self.mox.VerifyAll() def test_upload_data_to_store_duplicate(self): """See note in glance.api.v1.upload_utils on why we don't want image to be deleted in this case. """ self._test_upload_data_to_store_exception_with_notify( exception.Duplicate, webob.exc.HTTPConflict, image_killed=False) def test_upload_data_to_store_forbidden(self): self._test_upload_data_to_store_exception_with_notify( exception.Forbidden, webob.exc.HTTPForbidden) def test_upload_data_to_store_storage_full(self): self._test_upload_data_to_store_exception_with_notify( exception.StorageFull, webob.exc.HTTPRequestEntityTooLarge) def test_upload_data_to_store_storage_write_denied(self): self._test_upload_data_to_store_exception_with_notify( exception.StorageWriteDenied, webob.exc.HTTPServiceUnavailable) def test_upload_data_to_store_size_limit_exceeded(self): self._test_upload_data_to_store_exception_with_notify( exception.ImageSizeLimitExceeded, webob.exc.HTTPRequestEntityTooLarge) def test_upload_data_to_store_http_error(self): self._test_upload_data_to_store_exception_with_notify( webob.exc.HTTPError, webob.exc.HTTPError) def test_upload_data_to_store_client_disconnect(self): self._test_upload_data_to_store_exception( ValueError, webob.exc.HTTPBadRequest) def test_upload_data_to_store_client_disconnect_ioerror(self): self._test_upload_data_to_store_exception( IOError, webob.exc.HTTPBadRequest) def test_upload_data_to_store_exception(self): self._test_upload_data_to_store_exception_with_notify( Exception, webob.exc.HTTPInternalServerError) def test_upload_data_to_store_not_found_after_upload(self): req = unit_test_utils.get_fake_request() location = "file://foo/bar" size = 10 checksum = "checksum" image_meta = {'id': unit_test_utils.UUID1, 'size': size} image_data = "blah" notifier = self.mox.CreateMockAnything() store = self.mox.CreateMockAnything() store.add( image_meta['id'], mox.IgnoreArg(), image_meta['size']).AndReturn((location, size, checksum, {})) self.mox.StubOutWithMock(registry, "update_image_metadata") update_data = {'checksum': checksum, 'size': size} registry.update_image_metadata(req.context, image_meta['id'], update_data ).AndRaise(exception.NotFound) self.mox.StubOutWithMock(upload_utils, "initiate_deletion") upload_utils.initiate_deletion(req, location, image_meta['id'], mox.IsA(bool)) self.mox.StubOutWithMock(upload_utils, "safe_kill") upload_utils.safe_kill(req, image_meta['id']) notifier.error('image.upload', mox.IgnoreArg()) self.mox.ReplayAll() self.assertRaises(webob.exc.HTTPPreconditionFailed, upload_utils.upload_data_to_store, req, image_meta, image_data, store, notifier) self.mox.VerifyAll() glance-2014.1/glance/tests/unit/v1/test_api.py0000664000175400017540000051046412323736230022265 0ustar jenkinsjenkins00000000000000# -*- coding: utf-8 -*- # Copyright 2010-2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import copy import datetime import hashlib import uuid import mock from oslo.config import cfg import routes import six import webob import glance.api import glance.api.common from glance.api.v1 import router from glance.api.v1 import upload_utils import glance.common.config from glance.common import exception import glance.context from glance.db.sqlalchemy import api as db_api from glance.db.sqlalchemy import models as db_models from glance.openstack.common import jsonutils from glance.openstack.common import timeutils import glance.registry.client.v1.api as registry import glance.store.filesystem from glance.tests.unit import base import glance.tests.unit.utils as unit_test_utils from glance.tests import utils as test_utils CONF = cfg.CONF _gen_uuid = lambda: str(uuid.uuid4()) UUID1 = _gen_uuid() UUID2 = _gen_uuid() class TestGlanceAPI(base.IsolatedUnitTest): def setUp(self): """Establish a clean test environment""" super(TestGlanceAPI, self).setUp() self.mapper = routes.Mapper() self.api = test_utils.FakeAuthMiddleware(router.API(self.mapper)) self.FIXTURES = [ {'id': UUID1, 'name': 'fake image #1', 'status': 'active', 'disk_format': 'ami', 'container_format': 'ami', 'is_public': False, 'created_at': timeutils.utcnow(), 'updated_at': timeutils.utcnow(), 'deleted_at': None, 'deleted': False, 'checksum': None, 'size': 13, 'locations': [{'url': "file:///%s/%s" % (self.test_dir, UUID1), 'metadata': {}}], 'properties': {'type': 'kernel'}}, {'id': UUID2, 'name': 'fake image #2', 'status': 'active', 'disk_format': 'vhd', 'container_format': 'ovf', 'is_public': True, 'created_at': timeutils.utcnow(), 'updated_at': timeutils.utcnow(), 'deleted_at': None, 'deleted': False, 'checksum': 'abc123', 'size': 19, 'locations': [{'url': "file:///%s/%s" % (self.test_dir, UUID2), 'metadata': {}}], 'properties': {}}] self.context = glance.context.RequestContext(is_admin=True) db_api.get_engine() self.destroy_fixtures() self.create_fixtures() def tearDown(self): """Clear the test environment""" super(TestGlanceAPI, self).tearDown() self.destroy_fixtures() def create_fixtures(self): for fixture in self.FIXTURES: db_api.image_create(self.context, fixture) # We write a fake image file to the filesystem with open("%s/%s" % (self.test_dir, fixture['id']), 'wb') as image: image.write("chunk00000remainder") image.flush() def destroy_fixtures(self): # Easiest to just drop the models and re-create them... db_models.unregister_models(db_api.get_engine()) db_models.register_models(db_api.get_engine()) def _do_test_defaulted_format(self, format_key, format_value): fixture_headers = {'x-image-meta-name': 'defaulted', 'x-image-meta-location': 'http://localhost:0/image', format_key: format_value} req = webob.Request.blank("/images") req.method = 'POST' for k, v in fixture_headers.iteritems(): req.headers[k] = v res = req.get_response(self.api) self.assertEqual(res.status_int, 201) res_body = jsonutils.loads(res.body)['image'] self.assertEqual(format_value, res_body['disk_format']) self.assertEqual(format_value, res_body['container_format']) def test_defaulted_amazon_format(self): for key in ('x-image-meta-disk-format', 'x-image-meta-container-format'): for value in ('aki', 'ari', 'ami'): self._do_test_defaulted_format(key, value) def test_bad_min_disk_size_create(self): fixture_headers = {'x-image-meta-store': 'file', 'x-image-meta-disk-format': 'vhd', 'x-image-meta-container-format': 'ovf', 'x-image-meta-min-disk': '-42', 'x-image-meta-name': 'fake image #3'} req = webob.Request.blank("/images") req.method = 'POST' for k, v in fixture_headers.iteritems(): req.headers[k] = v res = req.get_response(self.api) self.assertEqual(res.status_int, 400) self.assertTrue('Invalid value' in res.body, res.body) def test_bad_min_disk_size_update(self): fixture_headers = {'x-image-meta-disk-format': 'vhd', 'x-image-meta-container-format': 'ovf', 'x-image-meta-name': 'fake image #3'} req = webob.Request.blank("/images") req.method = 'POST' for k, v in fixture_headers.iteritems(): req.headers[k] = v res = req.get_response(self.api) self.assertEqual(res.status_int, 201) res_body = jsonutils.loads(res.body)['image'] self.assertEqual('queued', res_body['status']) image_id = res_body['id'] req = webob.Request.blank("/images/%s" % image_id) req.method = 'PUT' req.headers['x-image-meta-min-disk'] = '-42' res = req.get_response(self.api) self.assertEqual(res.status_int, 400) self.assertTrue('Invalid value' in res.body, res.body) def test_bad_min_ram_size_create(self): fixture_headers = {'x-image-meta-store': 'file', 'x-image-meta-disk-format': 'vhd', 'x-image-meta-container-format': 'ovf', 'x-image-meta-min-ram': '-42', 'x-image-meta-name': 'fake image #3'} req = webob.Request.blank("/images") req.method = 'POST' for k, v in fixture_headers.iteritems(): req.headers[k] = v res = req.get_response(self.api) self.assertEqual(res.status_int, 400) self.assertTrue('Invalid value' in res.body, res.body) def test_bad_min_ram_size_update(self): fixture_headers = {'x-image-meta-disk-format': 'vhd', 'x-image-meta-container-format': 'ovf', 'x-image-meta-name': 'fake image #3'} req = webob.Request.blank("/images") req.method = 'POST' for k, v in fixture_headers.iteritems(): req.headers[k] = v res = req.get_response(self.api) self.assertEqual(res.status_int, 201) res_body = jsonutils.loads(res.body)['image'] self.assertEqual('queued', res_body['status']) image_id = res_body['id'] req = webob.Request.blank("/images/%s" % image_id) req.method = 'PUT' req.headers['x-image-meta-min-ram'] = '-42' res = req.get_response(self.api) self.assertEqual(res.status_int, 400) self.assertTrue('Invalid value' in res.body, res.body) def test_bad_disk_format(self): fixture_headers = { 'x-image-meta-store': 'bad', 'x-image-meta-name': 'bogus', 'x-image-meta-location': 'http://localhost:0/image.tar.gz', 'x-image-meta-disk-format': 'invalid', 'x-image-meta-container-format': 'ami', } req = webob.Request.blank("/images") req.method = 'POST' for k, v in fixture_headers.iteritems(): req.headers[k] = v res = req.get_response(self.api) self.assertEqual(res.status_int, 400) self.assertTrue('Invalid disk format' in res.body, res.body) def test_configured_disk_format_good(self): self.config(disk_formats=['foo'], group="image_format") fixture_headers = { 'x-image-meta-name': 'bogus', 'x-image-meta-location': 'http://localhost:0/image.tar.gz', 'x-image-meta-disk-format': 'foo', 'x-image-meta-container-format': 'bare', } req = webob.Request.blank("/images") req.method = 'POST' for k, v in fixture_headers.iteritems(): req.headers[k] = v res = req.get_response(self.api) self.assertEqual(res.status_int, 201) def test_configured_disk_format_bad(self): self.config(disk_formats=['foo'], group="image_format") fixture_headers = { 'x-image-meta-store': 'bad', 'x-image-meta-name': 'bogus', 'x-image-meta-location': 'http://localhost:0/image.tar.gz', 'x-image-meta-disk-format': 'bar', 'x-image-meta-container-format': 'bare', } req = webob.Request.blank("/images") req.method = 'POST' for k, v in fixture_headers.iteritems(): req.headers[k] = v res = req.get_response(self.api) self.assertEqual(res.status_int, 400) self.assertTrue('Invalid disk format' in res.body, res.body) def test_configured_container_format_good(self): self.config(container_formats=['foo'], group="image_format") fixture_headers = { 'x-image-meta-name': 'bogus', 'x-image-meta-location': 'http://localhost:0/image.tar.gz', 'x-image-meta-disk-format': 'raw', 'x-image-meta-container-format': 'foo', } req = webob.Request.blank("/images") req.method = 'POST' for k, v in fixture_headers.iteritems(): req.headers[k] = v res = req.get_response(self.api) self.assertEqual(res.status_int, 201) def test_configured_container_format_bad(self): self.config(container_formats=['foo'], group="image_format") fixture_headers = { 'x-image-meta-store': 'bad', 'x-image-meta-name': 'bogus', 'x-image-meta-location': 'http://localhost:0/image.tar.gz', 'x-image-meta-disk-format': 'raw', 'x-image-meta-container-format': 'bar', } req = webob.Request.blank("/images") req.method = 'POST' for k, v in fixture_headers.iteritems(): req.headers[k] = v res = req.get_response(self.api) self.assertEqual(res.status_int, 400) self.assertTrue('Invalid container format' in res.body, res.body) def test_container_and_disk_amazon_format_differs(self): fixture_headers = { 'x-image-meta-store': 'bad', 'x-image-meta-name': 'bogus', 'x-image-meta-location': 'http://localhost:0/image.tar.gz', 'x-image-meta-disk-format': 'aki', 'x-image-meta-container-format': 'ami'} req = webob.Request.blank("/images") req.method = 'POST' for k, v in fixture_headers.iteritems(): req.headers[k] = v res = req.get_response(self.api) expected = ("Invalid mix of disk and container formats. " "When setting a disk or container format to one of " "'aki', 'ari', or 'ami', " "the container and disk formats must match.") self.assertEqual(res.status_int, 400) self.assertTrue(expected in res.body, res.body) def test_create_with_location_no_container_format(self): fixture_headers = { 'x-image-meta-name': 'bogus', 'x-image-meta-location': 'http://localhost:0/image.tar.gz', 'x-image-meta-disk-format': 'vhd', } req = webob.Request.blank("/images") req.method = 'POST' for k, v in fixture_headers.iteritems(): req.headers[k] = v res = req.get_response(self.api) self.assertEqual(res.status_int, 400) self.assertTrue('Invalid container format' in res.body) def test_create_with_bad_store_name(self): fixture_headers = { 'x-image-meta-store': 'bad', 'x-image-meta-name': 'bogus', 'x-image-meta-disk-format': 'qcow2', 'x-image-meta-container-format': 'bare', } req = webob.Request.blank("/images") req.method = 'POST' for k, v in fixture_headers.iteritems(): req.headers[k] = v res = req.get_response(self.api) self.assertEqual(res.status_int, 400) self.assertTrue('Required store bad is invalid' in res.body) def test_create_with_location_unknown_scheme(self): fixture_headers = { 'x-image-meta-store': 'bad', 'x-image-meta-name': 'bogus', 'x-image-meta-location': 'bad+scheme://localhost:0/image.qcow2', 'x-image-meta-disk-format': 'qcow2', 'x-image-meta-container-format': 'bare', } req = webob.Request.blank("/images") req.method = 'POST' for k, v in fixture_headers.iteritems(): req.headers[k] = v res = req.get_response(self.api) self.assertEqual(res.status_int, 400) self.assertTrue('External sourcing not supported' in res.body) def test_create_with_location_bad_store_uri(self): fixture_headers = { 'x-image-meta-store': 'swift', 'x-image-meta-name': 'bogus', 'x-image-meta-location': 'http://', 'x-image-meta-disk-format': 'qcow2', 'x-image-meta-container-format': 'bare', } req = webob.Request.blank("/images") req.method = 'POST' for k, v in fixture_headers.iteritems(): req.headers[k] = v res = req.get_response(self.api) self.assertEqual(res.status_int, 400) self.assertTrue('Invalid location' in res.body) def test_create_image_with_too_many_properties(self): self.config(image_property_quota=1) another_request = unit_test_utils.get_fake_request( path='/images', method='POST') headers = {'x-auth-token': 'user:tenant:joe_soap', 'x-image-meta-property-x_all_permitted': '1', 'x-image-meta-property-x_all_permitted_foo': '2'} for k, v in headers.iteritems(): another_request.headers[k] = v output = another_request.get_response(self.api) self.assertEqual(output.status_int, 413) def test_bad_container_format(self): fixture_headers = { 'x-image-meta-store': 'bad', 'x-image-meta-name': 'bogus', 'x-image-meta-location': 'http://localhost:0/image.tar.gz', 'x-image-meta-disk-format': 'vhd', 'x-image-meta-container-format': 'invalid', } req = webob.Request.blank("/images") req.method = 'POST' for k, v in fixture_headers.iteritems(): req.headers[k] = v res = req.get_response(self.api) self.assertEqual(res.status_int, 400) self.assertTrue('Invalid container format' in res.body) def test_bad_image_size(self): fixture_headers = { 'x-image-meta-store': 'bad', 'x-image-meta-name': 'bogus', 'x-image-meta-location': 'http://example.com/image.tar.gz', 'x-image-meta-disk-format': 'vhd', 'x-image-meta-container-format': 'bare', } def exec_bad_size_test(bad_size, expected_substr): fixture_headers['x-image-meta-size'] = bad_size req = webob.Request.blank("/images", method='POST', headers=fixture_headers) res = req.get_response(self.api) self.assertEqual(res.status_int, 400) self.assertTrue(expected_substr in res.body) expected = "Cannot convert image size 'invalid' to an integer." exec_bad_size_test('invalid', expected) expected = "Image size must be >= 0 ('-10' specified)." exec_bad_size_test(-10, expected) def test_bad_image_name(self): fixture_headers = { 'x-image-meta-store': 'bad', 'x-image-meta-name': 'X' * 256, 'x-image-meta-location': 'http://example.com/image.tar.gz', 'x-image-meta-disk-format': 'vhd', 'x-image-meta-container-format': 'bare', } req = webob.Request.blank("/images") req.method = 'POST' for k, v in fixture_headers.iteritems(): req.headers[k] = v res = req.get_response(self.api) self.assertEqual(res.status_int, 400) def test_add_image_no_location_no_image_as_body(self): """Tests creates a queued image for no body and no loc header""" fixture_headers = {'x-image-meta-store': 'file', 'x-image-meta-disk-format': 'vhd', 'x-image-meta-container-format': 'ovf', 'x-image-meta-name': 'fake image #3'} req = webob.Request.blank("/images") req.method = 'POST' for k, v in fixture_headers.iteritems(): req.headers[k] = v res = req.get_response(self.api) self.assertEqual(res.status_int, 201) res_body = jsonutils.loads(res.body)['image'] self.assertEqual('queued', res_body['status']) image_id = res_body['id'] # Test that we are able to edit the Location field # per LP Bug #911599 req = webob.Request.blank("/images/%s" % image_id) req.method = 'PUT' req.headers['x-image-meta-location'] = 'http://localhost:0/images/123' res = req.get_response(self.api) self.assertEqual(res.status_int, 200) res_body = jsonutils.loads(res.body)['image'] # Once the location is set, the image should be activated # see LP Bug #939484 self.assertEqual('active', res_body['status']) self.assertFalse('location' in res_body) # location never shown def test_add_image_no_location_no_content_type(self): """Tests creates a queued image for no body and no loc header""" fixture_headers = {'x-image-meta-store': 'file', 'x-image-meta-disk-format': 'vhd', 'x-image-meta-container-format': 'ovf', 'x-image-meta-name': 'fake image #3'} req = webob.Request.blank("/images") req.method = 'POST' req.body = "chunk00000remainder" for k, v in fixture_headers.iteritems(): req.headers[k] = v res = req.get_response(self.api) self.assertEqual(res.status_int, 400) def test_add_image_size_header_too_big(self): """Tests raises BadRequest for supplied image size that is too big""" fixture_headers = {'x-image-meta-size': CONF.image_size_cap + 1, 'x-image-meta-name': 'fake image #3'} req = webob.Request.blank("/images") req.method = 'POST' for k, v in fixture_headers.iteritems(): req.headers[k] = v res = req.get_response(self.api) self.assertEqual(res.status_int, 400) def test_add_image_size_chunked_data_too_big(self): self.config(image_size_cap=512) fixture_headers = { 'x-image-meta-name': 'fake image #3', 'x-image-meta-container_format': 'ami', 'x-image-meta-disk_format': 'ami', 'transfer-encoding': 'chunked', 'content-type': 'application/octet-stream', } req = webob.Request.blank("/images") req.method = 'POST' req.body_file = six.StringIO('X' * (CONF.image_size_cap + 1)) for k, v in fixture_headers.iteritems(): req.headers[k] = v res = req.get_response(self.api) self.assertEqual(res.status_int, 413) def test_add_image_size_data_too_big(self): self.config(image_size_cap=512) fixture_headers = { 'x-image-meta-name': 'fake image #3', 'x-image-meta-container_format': 'ami', 'x-image-meta-disk_format': 'ami', 'content-type': 'application/octet-stream', } req = webob.Request.blank("/images") req.method = 'POST' req.body = 'X' * (CONF.image_size_cap + 1) for k, v in fixture_headers.iteritems(): req.headers[k] = v res = req.get_response(self.api) self.assertEqual(res.status_int, 400) def test_add_image_size_header_exceed_quota(self): quota = 500 self.config(user_storage_quota=quota) fixture_headers = {'x-image-meta-size': quota + 1, 'x-image-meta-name': 'fake image #3', 'x-image-meta-container_format': 'bare', 'x-image-meta-disk_format': 'qcow2', 'content-type': 'application/octet-stream', } req = webob.Request.blank("/images") req.method = 'POST' for k, v in fixture_headers.iteritems(): req.headers[k] = v req.body = 'X' * (quota + 1) res = req.get_response(self.api) self.assertEqual(res.status_int, 413) def test_add_image_size_data_exceed_quota(self): quota = 500 self.config(user_storage_quota=quota) fixture_headers = { 'x-image-meta-name': 'fake image #3', 'x-image-meta-container_format': 'bare', 'x-image-meta-disk_format': 'qcow2', 'content-type': 'application/octet-stream', } req = webob.Request.blank("/images") req.method = 'POST' req.body = 'X' * (quota + 1) for k, v in fixture_headers.iteritems(): req.headers[k] = v res = req.get_response(self.api) self.assertEqual(res.status_int, 413) def test_add_image_size_data_exceed_quota_readd(self): quota = 500 self.config(user_storage_quota=quota) fixture_headers = { 'x-image-meta-name': 'fake image #3', 'x-image-meta-container_format': 'bare', 'x-image-meta-disk_format': 'qcow2', 'content-type': 'application/octet-stream', } req = webob.Request.blank("/images") req.method = 'POST' req.body = 'X' * (quota + 1) for k, v in fixture_headers.iteritems(): req.headers[k] = v res = req.get_response(self.api) self.assertEqual(res.status_int, 413) used_size = sum([f['size'] for f in self.FIXTURES]) req = webob.Request.blank("/images") req.method = 'POST' req.body = 'X' * (quota - used_size) for k, v in fixture_headers.iteritems(): req.headers[k] = v res = req.get_response(self.api) self.assertEqual(res.status_int, 201) def _add_check_no_url_info(self): fixture_headers = {'x-image-meta-disk-format': 'ami', 'x-image-meta-container-format': 'ami', 'x-image-meta-size': '0', 'x-image-meta-name': 'empty image'} req = webob.Request.blank("/images") req.method = 'POST' for k, v in fixture_headers.iteritems(): req.headers[k] = v res = req.get_response(self.api) res_body = jsonutils.loads(res.body)['image'] self.assertFalse('locations' in res_body) self.assertFalse('direct_url' in res_body) image_id = res_body['id'] # HEAD empty image req = webob.Request.blank("/images/%s" % image_id) req.method = 'HEAD' res = req.get_response(self.api) self.assertEqual(res.status_int, 200) self.assertFalse('x-image-meta-locations' in res.headers) self.assertFalse('x-image-meta-direct_url' in res.headers) def test_add_check_no_url_info_ml(self): self.config(show_multiple_locations=True) self._add_check_no_url_info() def test_add_check_no_url_info_direct_url(self): self.config(show_image_direct_url=True) self._add_check_no_url_info() def test_add_check_no_url_info_both_on(self): self.config(show_image_direct_url=True) self.config(show_multiple_locations=True) self._add_check_no_url_info() def test_add_check_no_url_info_both_off(self): self._add_check_no_url_info() def test_add_image_zero_size(self): """Tests creating an active image with explicitly zero size""" fixture_headers = {'x-image-meta-disk-format': 'ami', 'x-image-meta-container-format': 'ami', 'x-image-meta-size': '0', 'x-image-meta-name': 'empty image'} req = webob.Request.blank("/images") req.method = 'POST' for k, v in fixture_headers.iteritems(): req.headers[k] = v res = req.get_response(self.api) self.assertEqual(res.status_int, 201) res_body = jsonutils.loads(res.body)['image'] self.assertEqual('active', res_body['status']) image_id = res_body['id'] # GET empty image req = webob.Request.blank("/images/%s" % image_id) res = req.get_response(self.api) self.assertEqual(res.status_int, 200) self.assertEqual(len(res.body), 0) def _do_test_add_image_attribute_mismatch(self, attributes): fixture_headers = { 'x-image-meta-name': 'fake image #3', } fixture_headers.update(attributes) req = webob.Request.blank("/images") req.method = 'POST' for k, v in fixture_headers.iteritems(): req.headers[k] = v req.headers['Content-Type'] = 'application/octet-stream' req.body = "XXXX" res = req.get_response(self.api) self.assertEqual(res.status_int, 400) def test_add_image_checksum_mismatch(self): attributes = { 'x-image-meta-checksum': 'asdf', } self._do_test_add_image_attribute_mismatch(attributes) def test_add_image_size_mismatch(self): attributes = { 'x-image-meta-size': str(len("XXXX") + 1), } self._do_test_add_image_attribute_mismatch(attributes) def test_add_image_checksum_and_size_mismatch(self): attributes = { 'x-image-meta-checksum': 'asdf', 'x-image-meta-size': str(len("XXXX") + 1), } self._do_test_add_image_attribute_mismatch(attributes) def test_add_image_bad_store(self): """Tests raises BadRequest for invalid store header""" fixture_headers = {'x-image-meta-store': 'bad', 'x-image-meta-name': 'fake image #3'} req = webob.Request.blank("/images") req.method = 'POST' for k, v in fixture_headers.iteritems(): req.headers[k] = v req.headers['Content-Type'] = 'application/octet-stream' req.body = "chunk00000remainder" res = req.get_response(self.api) self.assertEqual(res.status_int, 400) def test_add_image_basic_file_store(self): """Tests to add a basic image in the file store""" fixture_headers = {'x-image-meta-store': 'file', 'x-image-meta-disk-format': 'vhd', 'x-image-meta-container-format': 'ovf', 'x-image-meta-name': 'fake image #3'} req = webob.Request.blank("/images") req.method = 'POST' for k, v in fixture_headers.iteritems(): req.headers[k] = v req.headers['Content-Type'] = 'application/octet-stream' req.body = "chunk00000remainder" res = req.get_response(self.api) self.assertEqual(res.status_int, 201) # Test that the Location: header is set to the URI to # edit the newly-created image, as required by APP. # See LP Bug #719825 self.assertTrue('location' in res.headers, "'location' not in response headers.\n" "res.headerlist = %r" % res.headerlist) res_body = jsonutils.loads(res.body)['image'] self.assertTrue('/images/%s' % res_body['id'] in res.headers['location']) self.assertEqual('active', res_body['status']) image_id = res_body['id'] # Test that we are NOT able to edit the Location field # per LP Bug #911599 req = webob.Request.blank("/images/%s" % image_id) req.method = 'PUT' req.headers['x-image-meta-location'] = 'http://example.com/images/123' res = req.get_response(self.api) self.assertEqual(res.status_int, 400) def test_add_image_unauthorized(self): rules = {"add_image": '!'} self.set_policy_rules(rules) fixture_headers = {'x-image-meta-store': 'file', 'x-image-meta-disk-format': 'vhd', 'x-image-meta-container-format': 'ovf', 'x-image-meta-name': 'fake image #3'} req = webob.Request.blank("/images") req.method = 'POST' for k, v in fixture_headers.iteritems(): req.headers[k] = v req.headers['Content-Type'] = 'application/octet-stream' req.body = "chunk00000remainder" res = req.get_response(self.api) self.assertEqual(res.status_int, 403) def test_add_publicize_image_unauthorized(self): rules = {"add_image": '@', "modify_image": '@', "publicize_image": '!'} self.set_policy_rules(rules) fixture_headers = {'x-image-meta-store': 'file', 'x-image-meta-is-public': 'true', 'x-image-meta-disk-format': 'vhd', 'x-image-meta-container-format': 'ovf', 'x-image-meta-name': 'fake image #3'} req = webob.Request.blank("/images") req.method = 'POST' for k, v in fixture_headers.iteritems(): req.headers[k] = v req.headers['Content-Type'] = 'application/octet-stream' req.body = "chunk00000remainder" res = req.get_response(self.api) self.assertEqual(res.status_int, 403) def test_add_publicize_image_authorized(self): rules = {"add_image": '@', "modify_image": '@', "publicize_image": '@', "upload_image": '@'} self.set_policy_rules(rules) fixture_headers = {'x-image-meta-store': 'file', 'x-image-meta-is-public': 'true', 'x-image-meta-disk-format': 'vhd', 'x-image-meta-container-format': 'ovf', 'x-image-meta-name': 'fake image #3'} req = webob.Request.blank("/images") req.method = 'POST' for k, v in fixture_headers.iteritems(): req.headers[k] = v req.headers['Content-Type'] = 'application/octet-stream' req.body = "chunk00000remainder" res = req.get_response(self.api) self.assertEqual(res.status_int, 201) def test_add_copy_from_image_unauthorized(self): rules = {"add_image": '@', "copy_from": '!'} self.set_policy_rules(rules) fixture_headers = {'x-image-meta-store': 'file', 'x-image-meta-disk-format': 'vhd', 'x-glance-api-copy-from': 'http://glance.com/i.ovf', 'x-image-meta-container-format': 'ovf', 'x-image-meta-name': 'fake image #F'} req = webob.Request.blank("/images") req.method = 'POST' for k, v in fixture_headers.iteritems(): req.headers[k] = v req.headers['Content-Type'] = 'application/octet-stream' req.body = "chunk00000remainder" res = req.get_response(self.api) self.assertEqual(res.status_int, 403) def test_add_copy_from_upload_image_unauthorized(self): rules = {"add_image": '@', "copy_from": '@', "upload_image": '!'} self.set_policy_rules(rules) fixture_headers = {'x-image-meta-store': 'file', 'x-image-meta-disk-format': 'vhd', 'x-glance-api-copy-from': 'http://glance.com/i.ovf', 'x-image-meta-container-format': 'ovf', 'x-image-meta-name': 'fake image #F'} req = webob.Request.blank("/images") req.method = 'POST' for k, v in fixture_headers.iteritems(): req.headers[k] = v req.headers['Content-Type'] = 'application/octet-stream' res = req.get_response(self.api) self.assertEqual(res.status_int, 403) def test_add_copy_from_image_authorized_upload_image_authorized(self): rules = {"add_image": '@', "copy_from": '@', "upload_image": '@'} self.set_policy_rules(rules) fixture_headers = {'x-image-meta-store': 'file', 'x-image-meta-disk-format': 'vhd', 'x-glance-api-copy-from': 'http://glance.com/i.ovf', 'x-image-meta-container-format': 'ovf', 'x-image-meta-name': 'fake image #F'} req = webob.Request.blank("/images") req.method = 'POST' for k, v in fixture_headers.iteritems(): req.headers[k] = v req.headers['Content-Type'] = 'application/octet-stream' res = req.get_response(self.api) self.assertEqual(res.status_int, 201) def test_add_copy_from_with_nonempty_body(self): """Tests creates an image from copy-from and nonempty body""" fixture_headers = {'x-image-meta-store': 'file', 'x-image-meta-disk-format': 'vhd', 'x-glance-api-copy-from': 'http://a/b/c.ovf', 'x-image-meta-container-format': 'ovf', 'x-image-meta-name': 'fake image #F'} req = webob.Request.blank("/images") req.headers['Content-Type'] = 'application/octet-stream' req.method = 'POST' req.body = "chunk00000remainder" for k, v in fixture_headers.iteritems(): req.headers[k] = v res = req.get_response(self.api) self.assertEqual(res.status_int, 400) def test_add_location_with_nonempty_body(self): """Tests creates an image from location and nonempty body""" fixture_headers = {'x-image-meta-store': 'file', 'x-image-meta-disk-format': 'vhd', 'x-image-meta-location': 'http://a/b/c.tar.gz', 'x-image-meta-container-format': 'ovf', 'x-image-meta-name': 'fake image #F'} req = webob.Request.blank("/images") req.headers['Content-Type'] = 'application/octet-stream' req.method = 'POST' req.body = "chunk00000remainder" for k, v in fixture_headers.iteritems(): req.headers[k] = v res = req.get_response(self.api) self.assertEqual(res.status_int, 400) def test_add_location_with_conflict_image_size(self): """Tests creates an image from location and conflict image size""" self.stubs.Set(glance.api.v1.images, 'get_size_from_backend', lambda *args, **kwargs: 2) fixture_headers = {'x-image-meta-store': 'file', 'x-image-meta-disk-format': 'vhd', 'x-image-meta-location': 'http://a/b/c.tar.gz', 'x-image-meta-container-format': 'ovf', 'x-image-meta-name': 'fake image #F', 'x-image-meta-size': '1'} req = webob.Request.blank("/images") req.headers['Content-Type'] = 'application/octet-stream' req.method = 'POST' for k, v in fixture_headers.iteritems(): req.headers[k] = v res = req.get_response(self.api) self.assertEqual(res.status_int, 409) def test_add_copy_from_with_location(self): """Tests creates an image from copy-from and location""" fixture_headers = {'x-image-meta-store': 'file', 'x-image-meta-disk-format': 'vhd', 'x-glance-api-copy-from': 'http://a/b/c.ovf', 'x-image-meta-container-format': 'ovf', 'x-image-meta-name': 'fake image #F', 'x-image-meta-location': 'http://a/b/c.tar.gz'} req = webob.Request.blank("/images") req.method = 'POST' for k, v in fixture_headers.iteritems(): req.headers[k] = v res = req.get_response(self.api) self.assertEqual(res.status_int, 400) def test_add_copy_from_upload_image_unauthorized_with_body(self): rules = {"upload_image": '!', "modify_image": '@', "add_image": '@'} self.set_policy_rules(rules) self.config(image_size_cap=512) fixture_headers = { 'x-image-meta-name': 'fake image #3', 'x-image-meta-container_format': 'ami', 'x-image-meta-disk_format': 'ami', 'transfer-encoding': 'chunked', 'content-type': 'application/octet-stream', } req = webob.Request.blank("/images") req.method = 'POST' req.body_file = six.StringIO('X' * (CONF.image_size_cap)) for k, v in fixture_headers.iteritems(): req.headers[k] = v res = req.get_response(self.api) self.assertEqual(res.status_int, 403) def test_update_data_upload_bad_store_uri(self): fixture_headers = {'x-image-meta-name': 'fake image #3'} req = webob.Request.blank("/images") req.method = 'POST' for k, v in fixture_headers.iteritems(): req.headers[k] = v res = req.get_response(self.api) self.assertEqual(res.status_int, 201) res_body = jsonutils.loads(res.body)['image'] self.assertEqual('queued', res_body['status']) image_id = res_body['id'] req = webob.Request.blank("/images/%s" % image_id) req.method = 'PUT' req.headers['Content-Type'] = 'application/octet-stream' req.headers['x-image-disk-format'] = 'vhd' req.headers['x-image-container-format'] = 'ovf' req.headers['x-image-meta-location'] = 'http://' res = req.get_response(self.api) self.assertEqual(res.status_int, 400) self.assertTrue('Invalid location' in res.body) def test_update_data_upload_image_unauthorized(self): rules = {"upload_image": '!', "modify_image": '@', "add_image": '@'} self.set_policy_rules(rules) """Tests creates a queued image for no body and no loc header""" self.config(image_size_cap=512) fixture_headers = {'x-image-meta-store': 'file', 'x-image-meta-name': 'fake image #3'} req = webob.Request.blank("/images") req.method = 'POST' for k, v in fixture_headers.iteritems(): req.headers[k] = v res = req.get_response(self.api) self.assertEqual(res.status_int, 201) res_body = jsonutils.loads(res.body)['image'] self.assertEqual('queued', res_body['status']) image_id = res_body['id'] req = webob.Request.blank("/images/%s" % image_id) req.method = 'PUT' req.headers['Content-Type'] = 'application/octet-stream' req.headers['transfer-encoding'] = 'chunked' req.headers['x-image-disk-format'] = 'vhd' req.headers['x-image-container-format'] = 'ovf' req.body_file = six.StringIO('X' * (CONF.image_size_cap)) res = req.get_response(self.api) self.assertEqual(res.status_int, 403) def test_update_copy_from_upload_image_unauthorized(self): rules = {"upload_image": '!', "modify_image": '@', "add_image": '@', "copy_from": '@'} self.set_policy_rules(rules) fixture_headers = {'x-image-meta-disk-format': 'vhd', 'x-image-meta-container-format': 'ovf', 'x-image-meta-name': 'fake image #3'} req = webob.Request.blank("/images") req.method = 'POST' for k, v in fixture_headers.iteritems(): req.headers[k] = v res = req.get_response(self.api) self.assertEqual(res.status_int, 201) res_body = jsonutils.loads(res.body)['image'] self.assertEqual('queued', res_body['status']) image_id = res_body['id'] req = webob.Request.blank("/images/%s" % image_id) req.method = 'PUT' req.headers['Content-Type'] = 'application/octet-stream' req.headers['x-glance-api-copy-from'] = 'http://glance.com/i.ovf' res = req.get_response(self.api) self.assertEqual(res.status_int, 403) def test_update_copy_from_unauthorized(self): rules = {"upload_image": '@', "modify_image": '@', "add_image": '@', "copy_from": '!'} self.set_policy_rules(rules) fixture_headers = {'x-image-meta-disk-format': 'vhd', 'x-image-meta-container-format': 'ovf', 'x-image-meta-name': 'fake image #3'} req = webob.Request.blank("/images") req.method = 'POST' for k, v in fixture_headers.iteritems(): req.headers[k] = v res = req.get_response(self.api) self.assertEqual(res.status_int, 201) res_body = jsonutils.loads(res.body)['image'] self.assertEqual('queued', res_body['status']) image_id = res_body['id'] req = webob.Request.blank("/images/%s" % image_id) req.method = 'PUT' req.headers['Content-Type'] = 'application/octet-stream' req.headers['x-glance-api-copy-from'] = 'http://glance.com/i.ovf' res = req.get_response(self.api) self.assertEqual(res.status_int, 403) def _do_test_post_image_content_missing_format(self, missing): """Tests creation of an image with missing format""" fixture_headers = {'x-image-meta-store': 'file', 'x-image-meta-disk-format': 'vhd', 'x-image-meta-container-format': 'ovf', 'x-image-meta-name': 'fake image #3'} header = 'x-image-meta-' + missing.replace('_', '-') del fixture_headers[header] req = webob.Request.blank("/images") req.method = 'POST' for k, v in fixture_headers.iteritems(): req.headers[k] = v req.headers['Content-Type'] = 'application/octet-stream' req.body = "chunk00000remainder" res = req.get_response(self.api) self.assertEqual(res.status_int, 400) def test_post_image_content_missing_disk_format(self): """Tests creation of an image with missing disk format""" self._do_test_post_image_content_missing_format('disk_format') def test_post_image_content_missing_container_type(self): """Tests creation of an image with missing container format""" self._do_test_post_image_content_missing_format('container_format') def _do_test_put_image_content_missing_format(self, missing): """Tests delayed activation of an image with missing format""" fixture_headers = {'x-image-meta-store': 'file', 'x-image-meta-disk-format': 'vhd', 'x-image-meta-container-format': 'ovf', 'x-image-meta-name': 'fake image #3'} header = 'x-image-meta-' + missing.replace('_', '-') del fixture_headers[header] req = webob.Request.blank("/images") req.method = 'POST' for k, v in fixture_headers.iteritems(): req.headers[k] = v res = req.get_response(self.api) self.assertEqual(res.status_int, 201) res_body = jsonutils.loads(res.body)['image'] self.assertEqual('queued', res_body['status']) image_id = res_body['id'] req = webob.Request.blank("/images/%s" % image_id) req.method = 'PUT' for k, v in fixture_headers.iteritems(): req.headers[k] = v req.headers['Content-Type'] = 'application/octet-stream' req.body = "chunk00000remainder" res = req.get_response(self.api) self.assertEqual(res.status_int, 400) def test_put_image_content_missing_disk_format(self): """Tests delayed activation of image with missing disk format""" self._do_test_put_image_content_missing_format('disk_format') def test_put_image_content_missing_container_type(self): """Tests delayed activation of image with missing container format""" self._do_test_put_image_content_missing_format('container_format') def test_update_deleted_image(self): """Tests that exception raised trying to update a deleted image""" req = webob.Request.blank("/images/%s" % UUID2) req.method = 'DELETE' res = req.get_response(self.api) self.assertEqual(res.status_int, 200) fixture = {'name': 'test_del_img'} req = webob.Request.blank('/images/%s' % UUID2) req.method = 'PUT' req.content_type = 'application/json' req.body = jsonutils.dumps(dict(image=fixture)) res = req.get_response(self.api) self.assertEqual(res.status_int, 403) self.assertTrue('Forbidden to update deleted image' in res.body) def test_delete_deleted_image(self): """Tests that exception raised trying to delete a deleted image""" req = webob.Request.blank("/images/%s" % UUID2) req.method = 'DELETE' res = req.get_response(self.api) self.assertEqual(res.status_int, 200) # Verify the status is deleted req = webob.Request.blank("/images/%s" % UUID2) req.method = 'HEAD' res = req.get_response(self.api) self.assertEqual(res.status_int, 200) self.assertEqual("deleted", res.headers['x-image-meta-status']) req = webob.Request.blank("/images/%s" % UUID2) req.method = 'DELETE' res = req.get_response(self.api) self.assertEqual(res.status_int, 404) msg = "Image %s not found." % UUID2 self.assertTrue(msg in res.body) # Verify the status is still deleted req = webob.Request.blank("/images/%s" % UUID2) req.method = 'HEAD' res = req.get_response(self.api) self.assertEqual(res.status_int, 200) self.assertEqual("deleted", res.headers['x-image-meta-status']) @mock.patch.object(glance.store.filesystem.Store, 'delete') def test_image_status_when_delete_fails(self, mock_fsstore_delete): """ Tests that the image status set to active if deletion of image fails. """ mock_fsstore_delete.side_effect = exception.Forbidden() # trigger the v1 delete api req = webob.Request.blank("/images/%s" % UUID2) req.method = 'DELETE' res = req.get_response(self.api) self.assertEqual(res.status_int, 403) self.assertTrue('Forbidden to delete image' in res.body) # check image metadata is still there with active state req = webob.Request.blank("/images/%s" % UUID2) req.method = 'HEAD' res = req.get_response(self.api) self.assertEqual(res.status_int, 200) self.assertEqual("active", res.headers['x-image-meta-status']) def test_delete_pending_delete_image(self): """ Tests that correct response returned when deleting a pending_delete image """ # First deletion self.config(delayed_delete=True, scrubber_datadir='/tmp/scrubber') req = webob.Request.blank("/images/%s" % UUID2) req.method = 'DELETE' res = req.get_response(self.api) self.assertEqual(res.status_int, 200) # Verify the status is pending_delete req = webob.Request.blank("/images/%s" % UUID2) req.method = 'HEAD' res = req.get_response(self.api) self.assertEqual(res.status_int, 200) self.assertEqual("pending_delete", res.headers['x-image-meta-status']) # Second deletion req = webob.Request.blank("/images/%s" % UUID2) req.method = 'DELETE' res = req.get_response(self.api) self.assertEqual(res.status_int, 403) self.assertTrue('Forbidden to delete a pending_delete image' in res.body) # Verify the status is still pending_delete req = webob.Request.blank("/images/%s" % UUID2) req.method = 'HEAD' res = req.get_response(self.api) self.assertEqual(res.status_int, 200) self.assertEqual("pending_delete", res.headers['x-image-meta-status']) def test_upload_to_image_status_saving(self): """Test image upload conflict. If an image is uploaded before an existing upload operation completes to the same image, the original image should succeed and the conflicting should fail and any data deleted. """ fixture_headers = {'x-image-meta-store': 'file', 'x-image-meta-disk-format': 'vhd', 'x-image-meta-container-format': 'ovf', 'x-image-meta-name': 'some-foo-image'} # create an image but don't upload yet. req = webob.Request.blank("/images") req.method = 'POST' for k, v in fixture_headers.iteritems(): req.headers[k] = v res = req.get_response(self.api) self.assertEqual(res.status_int, 201) res_body = jsonutils.loads(res.body)['image'] image_id = res_body['id'] self.assertTrue('/images/%s' % image_id in res.headers['location']) # verify the status is 'queued' self.assertEqual('queued', res_body['status']) orig_get_image_metadata = registry.get_image_metadata orig_image_get = db_api._image_get orig_image_update = db_api._image_update # this will be used to track what is called and their order. called = [] # use this to determine if we are within a db session i.e. atomic # operation, that is setting our active state. test_status = {'activate_session_started': False} # We want first status check to be 'queued' so we get past the first # guard. test_status['queued_guard_passed'] = False def mock_image_update(context, values, image_id, purge_props=False, from_state=None): if values.get('status', None) == 'active': # We only expect this state to be entered once. if test_status['activate_session_started']: raise Exception("target session already started") test_status['activate_session_started'] = True called.append('update_active') return orig_image_update(context, values, image_id, purge_props=purge_props, from_state=from_state) def mock_image_get(*args, **kwargs): """Force status to 'saving' if not within activate db session. If we are in the activate db session we return 'active' which we then expect to cause exception.Conflict to be raised since this indicates that another upload has succeeded. """ image = orig_image_get(*args, **kwargs) if test_status['activate_session_started']: called.append('image_get_active') setattr(image, 'status', 'active') else: setattr(image, 'status', 'saving') return image def mock_get_image_metadata(*args, **kwargs): """Force image status sequence. """ called.append('get_image_meta') meta = orig_get_image_metadata(*args, **kwargs) if not test_status['queued_guard_passed']: meta['status'] = 'queued' test_status['queued_guard_passed'] = True return meta req = webob.Request.blank("/images/%s" % image_id) req.method = 'PUT' req.headers['Content-Type'] = \ 'application/octet-stream' req.body = "chunk00000remainder" mpo = mock.patch.object with mpo(upload_utils, 'initiate_deletion') as mock_initiate_deletion: with mpo(registry, 'get_image_metadata', mock_get_image_metadata): with mpo(db_api, '_image_get', mock_image_get): with mpo(db_api, '_image_update', mock_image_update): res = req.get_response(self.api) self.assertEqual(res.status_int, 409) # Check expected call sequence self.assertEqual(['get_image_meta', 'get_image_meta', 'update_active', 'image_get_active'], called) # Ensure cleanup occurred. self.assertTrue(mock_initiate_deletion.called) def test_register_and_upload(self): """ Test that the process of registering an image with some metadata, then uploading an image file with some more metadata doesn't mark the original metadata deleted :see LP Bug#901534 """ fixture_headers = {'x-image-meta-store': 'file', 'x-image-meta-disk-format': 'vhd', 'x-image-meta-container-format': 'ovf', 'x-image-meta-name': 'fake image #3', 'x-image-meta-property-key1': 'value1'} req = webob.Request.blank("/images") req.method = 'POST' for k, v in fixture_headers.iteritems(): req.headers[k] = v res = req.get_response(self.api) self.assertEqual(res.status_int, 201) res_body = jsonutils.loads(res.body)['image'] self.assertTrue('id' in res_body) image_id = res_body['id'] self.assertTrue('/images/%s' % image_id in res.headers['location']) # Verify the status is queued self.assertTrue('status' in res_body) self.assertEqual('queued', res_body['status']) # Check properties are not deleted self.assertTrue('properties' in res_body) self.assertTrue('key1' in res_body['properties']) self.assertEqual('value1', res_body['properties']['key1']) # Now upload the image file along with some more # metadata and verify original metadata properties # are not marked deleted req = webob.Request.blank("/images/%s" % image_id) req.method = 'PUT' req.headers['Content-Type'] = 'application/octet-stream' req.headers['x-image-meta-property-key2'] = 'value2' req.body = "chunk00000remainder" res = req.get_response(self.api) self.assertEqual(res.status_int, 200) # Verify the status is queued req = webob.Request.blank("/images/%s" % image_id) req.method = 'HEAD' res = req.get_response(self.api) self.assertEqual(res.status_int, 200) self.assertTrue('x-image-meta-property-key1' in res.headers, "Did not find required property in headers. " "Got headers: %r" % res.headers) self.assertEqual("active", res.headers['x-image-meta-status']) def test_delete_during_image_upload(self): req = unit_test_utils.get_fake_request() fixture_headers = {'x-image-meta-store': 'file', 'x-image-meta-disk-format': 'vhd', 'x-image-meta-container-format': 'ovf', 'x-image-meta-name': 'fake image #3', 'x-image-meta-property-key1': 'value1'} req = webob.Request.blank("/images") req.method = 'POST' for k, v in fixture_headers.iteritems(): req.headers[k] = v res = req.get_response(self.api) self.assertEqual(res.status_int, 201) res_body = jsonutils.loads(res.body)['image'] self.assertTrue('id' in res_body) image_id = res_body['id'] self.assertTrue('/images/%s' % image_id in res.headers['location']) # Verify the status is queued self.assertEqual('queued', res_body['status']) called = {'initiate_deletion': False} def mock_initiate_deletion(*args, **kwargs): called['initiate_deletion'] = True self.stubs.Set(glance.api.v1.upload_utils, 'initiate_deletion', mock_initiate_deletion) orig_update_image_metadata = registry.update_image_metadata ctlr = glance.api.v1.controller.BaseController orig_get_image_meta_or_404 = ctlr.get_image_meta_or_404 def mock_update_image_metadata(*args, **kwargs): if args[2].get('status', None) == 'deleted': # One shot. def mock_get_image_meta_or_404(*args, **kwargs): ret = orig_get_image_meta_or_404(*args, **kwargs) ret['status'] = 'queued' self.stubs.Set(ctlr, 'get_image_meta_or_404', orig_get_image_meta_or_404) return ret self.stubs.Set(ctlr, 'get_image_meta_or_404', mock_get_image_meta_or_404) req = webob.Request.blank("/images/%s" % image_id) req.method = 'PUT' req.headers['Content-Type'] = 'application/octet-stream' req.body = "somedata" res = req.get_response(self.api) self.assertEqual(res.status_int, 200) self.stubs.Set(registry, 'update_image_metadata', orig_update_image_metadata) return orig_update_image_metadata(*args, **kwargs) self.stubs.Set(registry, 'update_image_metadata', mock_update_image_metadata) req = webob.Request.blank("/images/%s" % image_id) req.method = 'DELETE' res = req.get_response(self.api) self.assertEqual(res.status_int, 200) self.assertTrue(called['initiate_deletion']) req = webob.Request.blank("/images/%s" % image_id) req.method = 'HEAD' res = req.get_response(self.api) self.assertEqual(res.status_int, 200) self.assertEqual(res.headers['x-image-meta-deleted'], 'True') self.assertEqual(res.headers['x-image-meta-status'], 'deleted') def test_disable_purge_props(self): """ Test the special x-glance-registry-purge-props header controls the purge property behaviour of the registry. :see LP Bug#901534 """ fixture_headers = {'x-image-meta-store': 'file', 'x-image-meta-disk-format': 'vhd', 'x-image-meta-container-format': 'ovf', 'x-image-meta-name': 'fake image #3', 'x-image-meta-property-key1': 'value1'} req = webob.Request.blank("/images") req.method = 'POST' for k, v in fixture_headers.iteritems(): req.headers[k] = v req.headers['Content-Type'] = 'application/octet-stream' req.body = "chunk00000remainder" res = req.get_response(self.api) self.assertEqual(res.status_int, 201) res_body = jsonutils.loads(res.body)['image'] self.assertTrue('id' in res_body) image_id = res_body['id'] self.assertTrue('/images/%s' % image_id in res.headers['location']) # Verify the status is queued self.assertTrue('status' in res_body) self.assertEqual('active', res_body['status']) # Check properties are not deleted self.assertTrue('properties' in res_body) self.assertTrue('key1' in res_body['properties']) self.assertEqual('value1', res_body['properties']['key1']) # Now update the image, setting new properties without # passing the x-glance-registry-purge-props header and # verify that original properties are marked deleted. req = webob.Request.blank("/images/%s" % image_id) req.method = 'PUT' req.headers['x-image-meta-property-key2'] = 'value2' res = req.get_response(self.api) self.assertEqual(res.status_int, 200) # Verify the original property no longer in headers req = webob.Request.blank("/images/%s" % image_id) req.method = 'HEAD' res = req.get_response(self.api) self.assertEqual(res.status_int, 200) self.assertTrue('x-image-meta-property-key2' in res.headers, "Did not find required property in headers. " "Got headers: %r" % res.headers) self.assertFalse('x-image-meta-property-key1' in res.headers, "Found property in headers that was not expected. " "Got headers: %r" % res.headers) # Now update the image, setting new properties and # passing the x-glance-registry-purge-props header with # a value of "false" and verify that second property # still appears in headers. req = webob.Request.blank("/images/%s" % image_id) req.method = 'PUT' req.headers['x-image-meta-property-key3'] = 'value3' req.headers['x-glance-registry-purge-props'] = 'false' res = req.get_response(self.api) self.assertEqual(res.status_int, 200) # Verify the second and third property in headers req = webob.Request.blank("/images/%s" % image_id) req.method = 'HEAD' res = req.get_response(self.api) self.assertEqual(res.status_int, 200) self.assertTrue('x-image-meta-property-key2' in res.headers, "Did not find required property in headers. " "Got headers: %r" % res.headers) self.assertTrue('x-image-meta-property-key3' in res.headers, "Did not find required property in headers. " "Got headers: %r" % res.headers) def test_publicize_image_unauthorized(self): """Create a non-public image then fail to make public""" rules = {"add_image": '@', "publicize_image": '!'} self.set_policy_rules(rules) fixture_headers = {'x-image-meta-store': 'file', 'x-image-meta-disk-format': 'vhd', 'x-image-meta-is-public': 'false', 'x-image-meta-container-format': 'ovf', 'x-image-meta-name': 'fake image #3'} req = webob.Request.blank("/images") req.method = 'POST' for k, v in fixture_headers.iteritems(): req.headers[k] = v res = req.get_response(self.api) self.assertEqual(res.status_int, 201) res_body = jsonutils.loads(res.body)['image'] req = webob.Request.blank("/images/%s" % res_body['id']) req.method = 'PUT' req.headers['x-image-meta-is-public'] = 'true' res = req.get_response(self.api) self.assertEqual(res.status_int, 403) def test_update_image_size_header_too_big(self): """Tests raises BadRequest for supplied image size that is too big""" fixture_headers = {'x-image-meta-size': CONF.image_size_cap + 1} req = webob.Request.blank("/images/%s" % UUID2) req.method = 'PUT' for k, v in fixture_headers.iteritems(): req.headers[k] = v res = req.get_response(self.api) self.assertEqual(res.status_int, 400) def test_update_image_size_data_too_big(self): self.config(image_size_cap=512) fixture_headers = {'content-type': 'application/octet-stream'} req = webob.Request.blank("/images/%s" % UUID2) req.method = 'PUT' req.body = 'X' * (CONF.image_size_cap + 1) for k, v in fixture_headers.iteritems(): req.headers[k] = v res = req.get_response(self.api) self.assertEqual(res.status_int, 400) def test_update_image_size_chunked_data_too_big(self): self.config(image_size_cap=512) # Create new image that has no data req = webob.Request.blank("/images") req.method = 'POST' req.headers['x-image-meta-name'] = 'something' req.headers['x-image-meta-container_format'] = 'ami' req.headers['x-image-meta-disk_format'] = 'ami' res = req.get_response(self.api) image_id = jsonutils.loads(res.body)['image']['id'] fixture_headers = { 'content-type': 'application/octet-stream', 'transfer-encoding': 'chunked', } req = webob.Request.blank("/images/%s" % image_id) req.method = 'PUT' req.body_file = six.StringIO('X' * (CONF.image_size_cap + 1)) for k, v in fixture_headers.iteritems(): req.headers[k] = v res = req.get_response(self.api) self.assertEqual(res.status_int, 413) def test_update_non_existing_image(self): self.config(image_size_cap=100) req = webob.Request.blank("images/%s" % _gen_uuid) req.method = 'PUT' req.body = 'test' req.headers['x-image-meta-name'] = 'test' req.headers['x-image-meta-container_format'] = 'ami' req.headers['x-image-meta-disk_format'] = 'ami' req.headers['x-image-meta-is_public'] = 'False' res = req.get_response(self.api) self.assertEqual(res.status_int, 404) def test_update_public_image(self): fixture_headers = {'x-image-meta-store': 'file', 'x-image-meta-disk-format': 'vhd', 'x-image-meta-is-public': 'true', 'x-image-meta-container-format': 'ovf', 'x-image-meta-name': 'fake image #3'} req = webob.Request.blank("/images") req.method = 'POST' for k, v in fixture_headers.iteritems(): req.headers[k] = v res = req.get_response(self.api) self.assertEqual(res.status_int, 201) res_body = jsonutils.loads(res.body)['image'] req = webob.Request.blank("/images/%s" % res_body['id']) req.method = 'PUT' req.headers['x-image-meta-name'] = 'updated public image' res = req.get_response(self.api) self.assertEqual(res.status_int, 200) def test_add_image_wrong_content_type(self): fixture_headers = { 'x-image-meta-name': 'fake image #3', 'x-image-meta-container_format': 'ami', 'x-image-meta-disk_format': 'ami', 'transfer-encoding': 'chunked', 'content-type': 'application/octet-st', } req = webob.Request.blank("/images") req.method = 'POST' for k, v in fixture_headers.iteritems(): req.headers[k] = v res = req.get_response(self.api) self.assertEqual(res.status_int, 400) def test_get_index_sort_name_asc(self): """ Tests that the /images registry API returns list of public images sorted alphabetically by name in ascending order. """ UUID3 = _gen_uuid() extra_fixture = {'id': UUID3, 'status': 'active', 'is_public': True, 'disk_format': 'vhd', 'container_format': 'ovf', 'name': 'asdf', 'size': 19, 'checksum': None} db_api.image_create(self.context, extra_fixture) UUID4 = _gen_uuid() extra_fixture = {'id': UUID4, 'status': 'active', 'is_public': True, 'disk_format': 'vhd', 'container_format': 'ovf', 'name': 'xyz', 'size': 20, 'checksum': None} db_api.image_create(self.context, extra_fixture) req = webob.Request.blank('/images?sort_key=name&sort_dir=asc') res = req.get_response(self.api) self.assertEqual(res.status_int, 200) res_dict = jsonutils.loads(res.body) images = res_dict['images'] self.assertEqual(len(images), 3) self.assertEqual(images[0]['id'], UUID3) self.assertEqual(images[1]['id'], UUID2) self.assertEqual(images[2]['id'], UUID4) def test_get_details_filter_changes_since(self): """ Tests that the /images/detail registry API returns list of public images that have a size less than or equal to size_max """ dt1 = timeutils.utcnow() - datetime.timedelta(1) iso1 = timeutils.isotime(dt1) date_only1 = dt1.strftime('%Y-%m-%d') date_only2 = dt1.strftime('%Y%m%d') date_only3 = dt1.strftime('%Y-%m%d') dt2 = timeutils.utcnow() + datetime.timedelta(1) iso2 = timeutils.isotime(dt2) image_ts = timeutils.utcnow() + datetime.timedelta(2) hour_before = image_ts.strftime('%Y-%m-%dT%H:%M:%S%%2B01:00') hour_after = image_ts.strftime('%Y-%m-%dT%H:%M:%S-01:00') dt4 = timeutils.utcnow() + datetime.timedelta(3) iso4 = timeutils.isotime(dt4) UUID3 = _gen_uuid() extra_fixture = {'id': UUID3, 'status': 'active', 'is_public': True, 'disk_format': 'vhd', 'container_format': 'ovf', 'name': 'fake image #3', 'size': 18, 'checksum': None} db_api.image_create(self.context, extra_fixture) db_api.image_destroy(self.context, UUID3) UUID4 = _gen_uuid() extra_fixture = {'id': UUID4, 'status': 'active', 'is_public': True, 'disk_format': 'ami', 'container_format': 'ami', 'name': 'fake image #4', 'size': 20, 'checksum': None, 'created_at': image_ts, 'updated_at': image_ts} db_api.image_create(self.context, extra_fixture) # Check a standard list, 4 images in db (2 deleted) req = webob.Request.blank('/images/detail') res = req.get_response(self.api) self.assertEqual(res.status_int, 200) res_dict = jsonutils.loads(res.body) images = res_dict['images'] self.assertEqual(len(images), 2) self.assertEqual(images[0]['id'], UUID4) self.assertEqual(images[1]['id'], UUID2) # Expect 3 images (1 deleted) req = webob.Request.blank('/images/detail?changes-since=%s' % iso1) res = req.get_response(self.api) self.assertEqual(res.status_int, 200) res_dict = jsonutils.loads(res.body) images = res_dict['images'] self.assertEqual(len(images), 3) self.assertEqual(images[0]['id'], UUID4) self.assertEqual(images[1]['id'], UUID3) # deleted self.assertEqual(images[2]['id'], UUID2) # Expect 1 images (0 deleted) req = webob.Request.blank('/images/detail?changes-since=%s' % iso2) res = req.get_response(self.api) self.assertEqual(res.status_int, 200) res_dict = jsonutils.loads(res.body) images = res_dict['images'] self.assertEqual(len(images), 1) self.assertEqual(images[0]['id'], UUID4) # Expect 1 images (0 deleted) req = webob.Request.blank('/images/detail?changes-since=%s' % hour_before) res = req.get_response(self.api) self.assertEqual(res.status_int, 200) res_dict = jsonutils.loads(res.body) images = res_dict['images'] self.assertEqual(len(images), 1) self.assertEqual(images[0]['id'], UUID4) # Expect 0 images (0 deleted) req = webob.Request.blank('/images/detail?changes-since=%s' % hour_after) res = req.get_response(self.api) self.assertEqual(res.status_int, 200) res_dict = jsonutils.loads(res.body) images = res_dict['images'] self.assertEqual(len(images), 0) # Expect 0 images (0 deleted) req = webob.Request.blank('/images/detail?changes-since=%s' % iso4) res = req.get_response(self.api) self.assertEqual(res.status_int, 200) res_dict = jsonutils.loads(res.body) images = res_dict['images'] self.assertEqual(len(images), 0) for param in [date_only1, date_only2, date_only3]: # Expect 3 images (1 deleted) req = webob.Request.blank('/images/detail?changes-since=%s' % param) res = req.get_response(self.api) self.assertEqual(res.status_int, 200) res_dict = jsonutils.loads(res.body) images = res_dict['images'] self.assertEqual(len(images), 3) self.assertEqual(images[0]['id'], UUID4) self.assertEqual(images[1]['id'], UUID3) # deleted self.assertEqual(images[2]['id'], UUID2) # Bad request (empty changes-since param) req = webob.Request.blank('/images/detail?changes-since=') res = req.get_response(self.api) self.assertEqual(res.status_int, 400) def test_get_images_bad_urls(self): """Check that routes collections are not on (LP bug 1185828)""" req = webob.Request.blank('/images/detail.xxx') res = req.get_response(self.api) self.assertEqual(res.status_int, 404) req = webob.Request.blank('/images.xxx') res = req.get_response(self.api) self.assertEqual(res.status_int, 404) req = webob.Request.blank('/images/new') res = req.get_response(self.api) self.assertEqual(res.status_int, 404) req = webob.Request.blank("/images/%s/members" % UUID1) res = req.get_response(self.api) self.assertEqual(res.status_int, 200) req = webob.Request.blank("/images/%s/members.xxx" % UUID1) res = req.get_response(self.api) self.assertEqual(res.status_int, 404) def test_get_index_filter_on_user_defined_properties(self): """Check that image filtering works on user-defined properties""" image1_id = _gen_uuid() properties = {'distro': 'ubuntu', 'arch': 'i386'} extra_fixture = {'id': image1_id, 'status': 'active', 'is_public': True, 'disk_format': 'vhd', 'container_format': 'ovf', 'name': 'image-extra-1', 'size': 18, 'properties': properties, 'checksum': None} db_api.image_create(self.context, extra_fixture) image2_id = _gen_uuid() properties = {'distro': 'ubuntu', 'arch': 'x86_64', 'foo': 'bar'} extra_fixture = {'id': image2_id, 'status': 'active', 'is_public': True, 'disk_format': 'ami', 'container_format': 'ami', 'name': 'image-extra-2', 'size': 20, 'properties': properties, 'checksum': None} db_api.image_create(self.context, extra_fixture) # Test index with filter containing one user-defined property. # Filter is 'property-distro=ubuntu'. # Verify both image1 and image2 are returned req = webob.Request.blank('/images?property-distro=ubuntu') res = req.get_response(self.api) self.assertEqual(res.status_int, 200) images = jsonutils.loads(res.body)['images'] self.assertEqual(len(images), 2) self.assertEqual(images[0]['id'], image2_id) self.assertEqual(images[1]['id'], image1_id) # Test index with filter containing one user-defined property but # non-existent value. Filter is 'property-distro=fedora'. # Verify neither images are returned req = webob.Request.blank('/images?property-distro=fedora') res = req.get_response(self.api) self.assertEqual(res.status_int, 200) images = jsonutils.loads(res.body)['images'] self.assertEqual(len(images), 0) # Test index with filter containing one user-defined property but # unique value. Filter is 'property-arch=i386'. # Verify only image1 is returned. req = webob.Request.blank('/images?property-arch=i386') res = req.get_response(self.api) self.assertEqual(res.status_int, 200) images = jsonutils.loads(res.body)['images'] self.assertEqual(len(images), 1) self.assertEqual(images[0]['id'], image1_id) # Test index with filter containing one user-defined property but # unique value. Filter is 'property-arch=x86_64'. # Verify only image1 is returned. req = webob.Request.blank('/images?property-arch=x86_64') res = req.get_response(self.api) self.assertEqual(res.status_int, 200) images = jsonutils.loads(res.body)['images'] self.assertEqual(len(images), 1) self.assertEqual(images[0]['id'], image2_id) # Test index with filter containing unique user-defined property. # Filter is 'property-foo=bar'. # Verify only image2 is returned. req = webob.Request.blank('/images?property-foo=bar') res = req.get_response(self.api) self.assertEqual(res.status_int, 200) images = jsonutils.loads(res.body)['images'] self.assertEqual(len(images), 1) self.assertEqual(images[0]['id'], image2_id) # Test index with filter containing unique user-defined property but # .value is non-existent. Filter is 'property-foo=baz'. # Verify neither images are returned. req = webob.Request.blank('/images?property-foo=baz') res = req.get_response(self.api) self.assertEqual(res.status_int, 200) images = jsonutils.loads(res.body)['images'] self.assertEqual(len(images), 0) # Test index with filter containing multiple user-defined properties # Filter is 'property-arch=x86_64&property-distro=ubuntu'. # Verify only image2 is returned. req = webob.Request.blank('/images?property-arch=x86_64&' 'property-distro=ubuntu') res = req.get_response(self.api) self.assertEqual(res.status_int, 200) images = jsonutils.loads(res.body)['images'] self.assertEqual(len(images), 1) self.assertEqual(images[0]['id'], image2_id) # Test index with filter containing multiple user-defined properties # Filter is 'property-arch=i386&property-distro=ubuntu'. # Verify only image1 is returned. req = webob.Request.blank('/images?property-arch=i386&' 'property-distro=ubuntu') res = req.get_response(self.api) self.assertEqual(res.status_int, 200) images = jsonutils.loads(res.body)['images'] self.assertEqual(len(images), 1) self.assertEqual(images[0]['id'], image1_id) # Test index with filter containing multiple user-defined properties. # Filter is 'property-arch=random&property-distro=ubuntu'. # Verify neither images are returned. req = webob.Request.blank('/images?property-arch=random&' 'property-distro=ubuntu') res = req.get_response(self.api) self.assertEqual(res.status_int, 200) images = jsonutils.loads(res.body)['images'] self.assertEqual(len(images), 0) # Test index with filter containing multiple user-defined properties. # Filter is 'property-arch=random&property-distro=random'. # Verify neither images are returned. req = webob.Request.blank('/images?property-arch=random&' 'property-distro=random') res = req.get_response(self.api) self.assertEqual(res.status_int, 200) images = jsonutils.loads(res.body)['images'] self.assertEqual(len(images), 0) # Test index with filter containing multiple user-defined properties. # Filter is 'property-boo=far&property-poo=far'. # Verify neither images are returned. req = webob.Request.blank('/images?property-boo=far&' 'property-poo=far') res = req.get_response(self.api) self.assertEqual(res.status_int, 200) images = jsonutils.loads(res.body)['images'] self.assertEqual(len(images), 0) # Test index with filter containing multiple user-defined properties. # Filter is 'property-foo=bar&property-poo=far'. # Verify neither images are returned. req = webob.Request.blank('/images?property-foo=bar&' 'property-poo=far') res = req.get_response(self.api) self.assertEqual(res.status_int, 200) images = jsonutils.loads(res.body)['images'] self.assertEqual(len(images), 0) def test_get_images_detailed_unauthorized(self): rules = {"get_images": '!'} self.set_policy_rules(rules) req = webob.Request.blank('/images/detail') res = req.get_response(self.api) self.assertEqual(res.status_int, 403) def test_get_images_unauthorized(self): rules = {"get_images": '!'} self.set_policy_rules(rules) req = webob.Request.blank('/images') res = req.get_response(self.api) self.assertEqual(res.status_int, 403) def test_store_location_not_revealed(self): """ Test that the internal store location is NOT revealed through the API server """ # Check index and details... for url in ('/images', '/images/detail'): req = webob.Request.blank(url) res = req.get_response(self.api) self.assertEqual(res.status_int, 200) res_dict = jsonutils.loads(res.body) images = res_dict['images'] num_locations = sum([1 for record in images if 'location' in record.keys()]) self.assertEqual(0, num_locations, images) # Check GET req = webob.Request.blank("/images/%s" % UUID2) res = req.get_response(self.api) self.assertEqual(res.status_int, 200) self.assertFalse('X-Image-Meta-Location' in res.headers) # Check HEAD req = webob.Request.blank("/images/%s" % UUID2) req.method = 'HEAD' res = req.get_response(self.api) self.assertEqual(res.status_int, 200) self.assertFalse('X-Image-Meta-Location' in res.headers) # Check PUT req = webob.Request.blank("/images/%s" % UUID2) req.body = res.body req.method = 'PUT' res = req.get_response(self.api) self.assertEqual(res.status_int, 200) res_body = jsonutils.loads(res.body) self.assertFalse('location' in res_body['image']) # Check POST req = webob.Request.blank("/images") headers = {'x-image-meta-location': 'http://localhost', 'x-image-meta-disk-format': 'vhd', 'x-image-meta-container-format': 'ovf', 'x-image-meta-name': 'fake image #3'} for k, v in headers.iteritems(): req.headers[k] = v req.method = 'POST' res = req.get_response(self.api) self.assertEqual(res.status_int, 201) res_body = jsonutils.loads(res.body) self.assertFalse('location' in res_body['image']) def test_image_is_checksummed(self): """Test that the image contents are checksummed properly""" fixture_headers = {'x-image-meta-store': 'file', 'x-image-meta-disk-format': 'vhd', 'x-image-meta-container-format': 'ovf', 'x-image-meta-name': 'fake image #3'} image_contents = "chunk00000remainder" image_checksum = hashlib.md5(image_contents).hexdigest() req = webob.Request.blank("/images") req.method = 'POST' for k, v in fixture_headers.iteritems(): req.headers[k] = v req.headers['Content-Type'] = 'application/octet-stream' req.body = image_contents res = req.get_response(self.api) self.assertEqual(res.status_int, 201) res_body = jsonutils.loads(res.body)['image'] self.assertEqual(image_checksum, res_body['checksum'], "Mismatched checksum. Expected %s, got %s" % (image_checksum, res_body['checksum'])) def test_etag_equals_checksum_header(self): """Test that the ETag header matches the x-image-meta-checksum""" fixture_headers = {'x-image-meta-store': 'file', 'x-image-meta-disk-format': 'vhd', 'x-image-meta-container-format': 'ovf', 'x-image-meta-name': 'fake image #3'} image_contents = "chunk00000remainder" image_checksum = hashlib.md5(image_contents).hexdigest() req = webob.Request.blank("/images") req.method = 'POST' for k, v in fixture_headers.iteritems(): req.headers[k] = v req.headers['Content-Type'] = 'application/octet-stream' req.body = image_contents res = req.get_response(self.api) self.assertEqual(res.status_int, 201) image = jsonutils.loads(res.body)['image'] # HEAD the image and check the ETag equals the checksum header... expected_headers = {'x-image-meta-checksum': image_checksum, 'etag': image_checksum} req = webob.Request.blank("/images/%s" % image['id']) req.method = 'HEAD' res = req.get_response(self.api) self.assertEqual(res.status_int, 200) for key in expected_headers.keys(): self.assertTrue(key in res.headers, "required header '%s' missing from " "returned headers" % key) for key, value in expected_headers.iteritems(): self.assertEqual(value, res.headers[key]) def test_bad_checksum_prevents_image_creation(self): """Test that the image contents are checksummed properly""" image_contents = "chunk00000remainder" bad_checksum = hashlib.md5("invalid").hexdigest() fixture_headers = {'x-image-meta-store': 'file', 'x-image-meta-disk-format': 'vhd', 'x-image-meta-container-format': 'ovf', 'x-image-meta-name': 'fake image #3', 'x-image-meta-checksum': bad_checksum, 'x-image-meta-is-public': 'true'} req = webob.Request.blank("/images") req.method = 'POST' for k, v in fixture_headers.iteritems(): req.headers[k] = v req.headers['Content-Type'] = 'application/octet-stream' req.body = image_contents res = req.get_response(self.api) self.assertEqual(res.status_int, 400) # Test that only one image was returned (that already exists) req = webob.Request.blank("/images") req.method = 'GET' res = req.get_response(self.api) self.assertEqual(res.status_int, 200) images = jsonutils.loads(res.body)['images'] self.assertEqual(len(images), 1) def test_image_meta(self): """Test for HEAD /images/""" expected_headers = {'x-image-meta-id': UUID2, 'x-image-meta-name': 'fake image #2'} req = webob.Request.blank("/images/%s" % UUID2) req.method = 'HEAD' res = req.get_response(self.api) self.assertEqual(res.status_int, 200) for key, value in expected_headers.iteritems(): self.assertEqual(value, res.headers[key]) def test_image_meta_unauthorized(self): rules = {"get_image": '!'} self.set_policy_rules(rules) req = webob.Request.blank("/images/%s" % UUID2) req.method = 'HEAD' res = req.get_response(self.api) self.assertEqual(res.status_int, 403) def test_show_image_basic(self): req = webob.Request.blank("/images/%s" % UUID2) res = req.get_response(self.api) self.assertEqual(res.status_int, 200) self.assertEqual(res.content_type, 'application/octet-stream') self.assertEqual('chunk00000remainder', res.body) def test_show_non_exists_image(self): req = webob.Request.blank("/images/%s" % _gen_uuid()) res = req.get_response(self.api) self.assertEqual(res.status_int, 404) def test_show_image_unauthorized(self): rules = {"get_image": '!'} self.set_policy_rules(rules) req = webob.Request.blank("/images/%s" % UUID2) res = req.get_response(self.api) self.assertEqual(res.status_int, 403) def test_show_image_unauthorized_download(self): rules = {"download_image": '!'} self.set_policy_rules(rules) req = webob.Request.blank("/images/%s" % UUID2) res = req.get_response(self.api) self.assertEqual(res.status_int, 403) def test_delete_image(self): req = webob.Request.blank("/images/%s" % UUID2) req.method = 'DELETE' res = req.get_response(self.api) self.assertEqual(res.status_int, 200) self.assertEqual(res.body, '') req = webob.Request.blank("/images/%s" % UUID2) req.method = 'GET' res = req.get_response(self.api) self.assertEqual(res.status_int, 404, res.body) req = webob.Request.blank("/images/%s" % UUID2) req.method = 'HEAD' res = req.get_response(self.api) self.assertEqual(res.status_int, 200) self.assertEqual(res.headers['x-image-meta-deleted'], 'True') self.assertEqual(res.headers['x-image-meta-status'], 'deleted') def test_delete_non_exists_image(self): req = webob.Request.blank("/images/%s" % _gen_uuid()) req.method = 'DELETE' res = req.get_response(self.api) self.assertEqual(res.status_int, 404) def test_delete_not_allowed(self): # Verify we can get the image data req = webob.Request.blank("/images/%s" % UUID2) req.method = 'GET' req.headers['X-Auth-Token'] = 'user:tenant:' res = req.get_response(self.api) self.assertEqual(res.status_int, 200) self.assertEqual(len(res.body), 19) # Verify we cannot delete the image req.method = 'DELETE' res = req.get_response(self.api) self.assertEqual(res.status_int, 403) # Verify the image data is still there req.method = 'GET' res = req.get_response(self.api) self.assertEqual(res.status_int, 200) self.assertEqual(len(res.body), 19) def test_delete_queued_image(self): """Delete an image in a queued state Bug #747799 demonstrated that trying to DELETE an image that had had its save process killed manually results in failure because the location attribute is None. Bug #1048851 demonstrated that the status was not properly being updated to 'deleted' from 'queued'. """ fixture_headers = {'x-image-meta-store': 'file', 'x-image-meta-disk-format': 'vhd', 'x-image-meta-container-format': 'ovf', 'x-image-meta-name': 'fake image #3'} req = webob.Request.blank("/images") req.method = 'POST' for k, v in fixture_headers.iteritems(): req.headers[k] = v res = req.get_response(self.api) self.assertEqual(res.status_int, 201) res_body = jsonutils.loads(res.body)['image'] self.assertEqual('queued', res_body['status']) # Now try to delete the image... req = webob.Request.blank("/images/%s" % res_body['id']) req.method = 'DELETE' res = req.get_response(self.api) self.assertEqual(res.status_int, 200) req = webob.Request.blank('/images/%s' % res_body['id']) req.method = 'HEAD' res = req.get_response(self.api) self.assertEqual(res.status_int, 200) self.assertEqual(res.headers['x-image-meta-deleted'], 'True') self.assertEqual(res.headers['x-image-meta-status'], 'deleted') def test_delete_queued_image_delayed_delete(self): """Delete an image in a queued state when delayed_delete is on Bug #1048851 demonstrated that the status was not properly being updated to 'deleted' from 'queued'. """ self.config(delayed_delete=True) fixture_headers = {'x-image-meta-store': 'file', 'x-image-meta-disk-format': 'vhd', 'x-image-meta-container-format': 'ovf', 'x-image-meta-name': 'fake image #3'} req = webob.Request.blank("/images") req.method = 'POST' for k, v in fixture_headers.iteritems(): req.headers[k] = v res = req.get_response(self.api) self.assertEqual(res.status_int, 201) res_body = jsonutils.loads(res.body)['image'] self.assertEqual('queued', res_body['status']) # Now try to delete the image... req = webob.Request.blank("/images/%s" % res_body['id']) req.method = 'DELETE' res = req.get_response(self.api) self.assertEqual(res.status_int, 200) req = webob.Request.blank('/images/%s' % res_body['id']) req.method = 'HEAD' res = req.get_response(self.api) self.assertEqual(res.status_int, 200) self.assertEqual(res.headers['x-image-meta-deleted'], 'True') self.assertEqual(res.headers['x-image-meta-status'], 'deleted') def test_delete_protected_image(self): fixture_headers = {'x-image-meta-store': 'file', 'x-image-meta-name': 'fake image #3', 'x-image-meta-disk-format': 'vhd', 'x-image-meta-container-format': 'ovf', 'x-image-meta-protected': 'True'} req = webob.Request.blank("/images") req.method = 'POST' for k, v in fixture_headers.iteritems(): req.headers[k] = v res = req.get_response(self.api) self.assertEqual(res.status_int, 201) res_body = jsonutils.loads(res.body)['image'] self.assertEqual('queued', res_body['status']) # Now try to delete the image... req = webob.Request.blank("/images/%s" % res_body['id']) req.method = 'DELETE' res = req.get_response(self.api) self.assertEqual(res.status_int, 403) def test_delete_image_unauthorized(self): rules = {"delete_image": '!'} self.set_policy_rules(rules) req = webob.Request.blank("/images/%s" % UUID2) req.method = 'DELETE' res = req.get_response(self.api) self.assertEqual(res.status_int, 403) def test_get_details_invalid_marker(self): """ Tests that the /images/detail registry API returns a 400 when an invalid marker is provided """ req = webob.Request.blank('/images/detail?marker=%s' % _gen_uuid()) res = req.get_response(self.api) self.assertEqual(res.status_int, 400) def test_get_image_members(self): """ Tests members listing for existing images """ req = webob.Request.blank('/images/%s/members' % UUID2) req.method = 'GET' res = req.get_response(self.api) self.assertEqual(res.status_int, 200) memb_list = jsonutils.loads(res.body) num_members = len(memb_list['members']) self.assertEqual(num_members, 0) def test_get_image_members_allowed_by_policy(self): rules = {"get_members": '@'} self.set_policy_rules(rules) req = webob.Request.blank('/images/%s/members' % UUID2) req.method = 'GET' res = req.get_response(self.api) self.assertEqual(res.status_int, 200) memb_list = jsonutils.loads(res.body) num_members = len(memb_list['members']) self.assertEqual(num_members, 0) def test_get_image_members_forbidden_by_policy(self): rules = {"get_members": '!'} self.set_policy_rules(rules) req = webob.Request.blank('/images/%s/members' % UUID2) req.method = 'GET' res = req.get_response(self.api) self.assertEqual(res.status_int, webob.exc.HTTPForbidden.code) def test_get_image_members_not_existing(self): """ Tests proper exception is raised if attempt to get members of non-existing image """ req = webob.Request.blank('/images/%s/members' % _gen_uuid()) req.method = 'GET' res = req.get_response(self.api) self.assertEqual(res.status_int, 404) def test_add_member_positive(self): """ Tests adding image members """ test_router_api = router.API(self.mapper) self.api = test_utils.FakeAuthMiddleware( test_router_api, is_admin=True) req = webob.Request.blank('/images/%s/members/pattieblack' % UUID2) req.method = 'PUT' res = req.get_response(self.api) self.assertEqual(res.status_int, 204) def test_get_member_images(self): """ Tests image listing for members """ req = webob.Request.blank('/shared-images/pattieblack') req.method = 'GET' res = req.get_response(self.api) self.assertEqual(res.status_int, 200) memb_list = jsonutils.loads(res.body) num_members = len(memb_list['shared_images']) self.assertEqual(num_members, 0) def test_replace_members(self): """ Tests replacing image members raises right exception """ test_router_api = router.API(self.mapper) self.api = test_utils.FakeAuthMiddleware( test_router_api, is_admin=False) fixture = dict(member_id='pattieblack') req = webob.Request.blank('/images/%s/members' % UUID2) req.method = 'PUT' req.content_type = 'application/json' req.body = jsonutils.dumps(dict(image_memberships=fixture)) res = req.get_response(self.api) self.assertEqual(res.status_int, 401) def test_active_image_immutable_props_for_user(self): """ Tests user cannot update immutable props of active image """ test_router_api = router.API(self.mapper) self.api = test_utils.FakeAuthMiddleware( test_router_api, is_admin=False) fixture_header_list = [{'x-image-meta-checksum': '1234'}, {'x-image-meta-size': '12345'}] for fixture_header in fixture_header_list: req = webob.Request.blank('/images/%s' % UUID2) req.method = 'PUT' for k, v in fixture_header.iteritems(): req = webob.Request.blank('/images/%s' % UUID2) req.method = 'HEAD' res = req.get_response(self.api) self.assertEqual(res.status_int, 200) orig_value = res.headers[k] req = webob.Request.blank('/images/%s' % UUID2) req.headers[k] = v req.method = 'PUT' res = req.get_response(self.api) self.assertEqual(res.status_int, 403) prop = k[len('x-image-meta-'):] self.assertNotEqual(res.body.find("Forbidden to modify '%s' " "of active " "image" % prop), -1) req = webob.Request.blank('/images/%s' % UUID2) req.method = 'HEAD' res = req.get_response(self.api) self.assertEqual(res.status_int, 200) self.assertEqual(orig_value, res.headers[k]) def test_props_of_active_image_mutable_for_admin(self): """ Tests admin can update 'immutable' props of active image """ test_router_api = router.API(self.mapper) self.api = test_utils.FakeAuthMiddleware( test_router_api, is_admin=True) fixture_header_list = [{'x-image-meta-checksum': '1234'}, {'x-image-meta-size': '12345'}] for fixture_header in fixture_header_list: req = webob.Request.blank('/images/%s' % UUID2) req.method = 'PUT' for k, v in fixture_header.iteritems(): req = webob.Request.blank('/images/%s' % UUID2) req.method = 'HEAD' res = req.get_response(self.api) self.assertEqual(res.status_int, 200) req = webob.Request.blank('/images/%s' % UUID2) req.headers[k] = v req.method = 'PUT' res = req.get_response(self.api) self.assertEqual(res.status_int, 200) req = webob.Request.blank('/images/%s' % UUID2) req.method = 'HEAD' res = req.get_response(self.api) self.assertEqual(res.status_int, 200) self.assertEqual(v, res.headers[k]) def test_replace_members_non_existing_image(self): """ Tests replacing image members raises right exception """ test_router_api = router.API(self.mapper) self.api = test_utils.FakeAuthMiddleware( test_router_api, is_admin=True) fixture = dict(member_id='pattieblack') req = webob.Request.blank('/images/%s/members' % _gen_uuid()) req.method = 'PUT' req.content_type = 'application/json' req.body = jsonutils.dumps(dict(image_memberships=fixture)) res = req.get_response(self.api) self.assertEqual(res.status_int, 404) def test_replace_members_bad_request(self): """ Tests replacing image members raises bad request if body is wrong """ test_router_api = router.API(self.mapper) self.api = test_utils.FakeAuthMiddleware( test_router_api, is_admin=True) fixture = dict(member_id='pattieblack') req = webob.Request.blank('/images/%s/members' % UUID2) req.method = 'PUT' req.content_type = 'application/json' req.body = jsonutils.dumps(dict(image_memberships=fixture)) res = req.get_response(self.api) self.assertEqual(res.status_int, 400) def test_replace_members_positive(self): """ Tests replacing image members """ test_router = router.API(self.mapper) self.api = test_utils.FakeAuthMiddleware( test_router, is_admin=True) fixture = [dict(member_id='pattieblack', can_share=False)] # Replace req = webob.Request.blank('/images/%s/members' % UUID2) req.method = 'PUT' req.content_type = 'application/json' req.body = jsonutils.dumps(dict(memberships=fixture)) res = req.get_response(self.api) self.assertEqual(res.status_int, 204) def test_replace_members_forbidden_by_policy(self): rules = {"modify_member": '!'} self.set_policy_rules(rules) self.api = test_utils.FakeAuthMiddleware(router.API(self.mapper), is_admin=True) fixture = [{'member_id': 'pattieblack', 'can_share': 'false'}] req = webob.Request.blank('/images/%s/members' % UUID1) req.method = 'PUT' req.content_type = 'application/json' req.body = jsonutils.dumps(dict(memberships=fixture)) res = req.get_response(self.api) self.assertEqual(res.status_int, webob.exc.HTTPForbidden.code) def test_replace_members_allowed_by_policy(self): rules = {"modify_member": '@'} self.set_policy_rules(rules) self.api = test_utils.FakeAuthMiddleware(router.API(self.mapper), is_admin=True) fixture = [{'member_id': 'pattieblack', 'can_share': 'false'}] req = webob.Request.blank('/images/%s/members' % UUID1) req.method = 'PUT' req.content_type = 'application/json' req.body = jsonutils.dumps(dict(memberships=fixture)) res = req.get_response(self.api) self.assertEqual(res.status_int, webob.exc.HTTPNoContent.code) def test_add_member_unauthorized(self): """ Tests adding image members raises right exception """ test_router = router.API(self.mapper) self.api = test_utils.FakeAuthMiddleware( test_router, is_admin=False) req = webob.Request.blank('/images/%s/members/pattieblack' % UUID2) req.method = 'PUT' res = req.get_response(self.api) self.assertEqual(res.status_int, 401) def test_add_member_non_existing_image(self): """ Tests adding image members raises right exception """ test_router = router.API(self.mapper) self.api = test_utils.FakeAuthMiddleware( test_router, is_admin=True) test_uri = '/images/%s/members/pattieblack' req = webob.Request.blank(test_uri % _gen_uuid()) req.method = 'PUT' res = req.get_response(self.api) self.assertEqual(res.status_int, 404) def test_add_member_with_body(self): """ Tests adding image members """ fixture = dict(can_share=True) test_router = router.API(self.mapper) self.api = test_utils.FakeAuthMiddleware( test_router, is_admin=True) req = webob.Request.blank('/images/%s/members/pattieblack' % UUID2) req.method = 'PUT' req.body = jsonutils.dumps(dict(member=fixture)) res = req.get_response(self.api) self.assertEqual(res.status_int, 204) def test_add_member_overlimit(self): self.config(image_member_quota=0) test_router_api = router.API(self.mapper) self.api = test_utils.FakeAuthMiddleware( test_router_api, is_admin=True) req = webob.Request.blank('/images/%s/members/pattieblack' % UUID2) req.method = 'PUT' res = req.get_response(self.api) self.assertEqual(res.status_int, 413) def test_add_member_unlimited(self): self.config(image_member_quota=-1) test_router_api = router.API(self.mapper) self.api = test_utils.FakeAuthMiddleware( test_router_api, is_admin=True) req = webob.Request.blank('/images/%s/members/pattieblack' % UUID2) req.method = 'PUT' res = req.get_response(self.api) self.assertEqual(res.status_int, 204) def test_add_member_forbidden_by_policy(self): rules = {"modify_member": '!'} self.set_policy_rules(rules) self.api = test_utils.FakeAuthMiddleware(router.API(self.mapper), is_admin=True) req = webob.Request.blank('/images/%s/members/pattieblack' % UUID1) req.method = 'PUT' res = req.get_response(self.api) self.assertEqual(res.status_int, webob.exc.HTTPForbidden.code) def test_add_member_allowed_by_policy(self): rules = {"modify_member": '@'} self.set_policy_rules(rules) self.api = test_utils.FakeAuthMiddleware(router.API(self.mapper), is_admin=True) req = webob.Request.blank('/images/%s/members/pattieblack' % UUID1) req.method = 'PUT' res = req.get_response(self.api) self.assertEqual(res.status_int, webob.exc.HTTPNoContent.code) def test_get_members_of_deleted_image_raises_404(self): """ Tests members listing for deleted image raises 404. """ req = webob.Request.blank("/images/%s" % UUID2) req.method = 'DELETE' res = req.get_response(self.api) self.assertEqual(res.status_int, 200) req = webob.Request.blank('/images/%s/members' % UUID2) req.method = 'GET' res = req.get_response(self.api) self.assertEqual(res.status_int, webob.exc.HTTPNotFound.code) self.assertTrue( 'Image with identifier %s has been deleted.' % UUID2 in res.body) def test_delete_member_of_deleted_image_raises_404(self): """ Tests deleting members of deleted image raises 404. """ test_router = router.API(self.mapper) self.api = test_utils.FakeAuthMiddleware(test_router, is_admin=True) req = webob.Request.blank("/images/%s" % UUID2) req.method = 'DELETE' res = req.get_response(self.api) self.assertEqual(res.status_int, 200) req = webob.Request.blank('/images/%s/members/pattieblack' % UUID2) req.method = 'DELETE' res = req.get_response(self.api) self.assertEqual(res.status_int, webob.exc.HTTPNotFound.code) self.assertTrue( 'Image with identifier %s has been deleted.' % UUID2 in res.body) def test_update_members_of_deleted_image_raises_404(self): """ Tests update members of deleted image raises 404. """ test_router = router.API(self.mapper) self.api = test_utils.FakeAuthMiddleware(test_router, is_admin=True) req = webob.Request.blank('/images/%s/members/pattieblack' % UUID2) req.method = 'PUT' res = req.get_response(self.api) self.assertEqual(res.status_int, 204) req = webob.Request.blank("/images/%s" % UUID2) req.method = 'DELETE' res = req.get_response(self.api) self.assertEqual(res.status_int, 200) fixture = [{'member_id': 'pattieblack', 'can_share': 'false'}] req = webob.Request.blank('/images/%s/members' % UUID2) req.method = 'PUT' req.content_type = 'application/json' req.body = jsonutils.dumps(dict(memberships=fixture)) res = req.get_response(self.api) self.assertEqual(res.status_int, webob.exc.HTTPNotFound.code) self.assertTrue( 'Image with identifier %s has been deleted.' % UUID2 in res.body) def test_replace_members_of_image(self): test_router = router.API(self.mapper) self.api = test_utils.FakeAuthMiddleware(test_router, is_admin=True) fixture = [{'member_id': 'pattieblack', 'can_share': 'false'}] req = webob.Request.blank('/images/%s/members' % UUID2) req.method = 'PUT' req.body = jsonutils.dumps(dict(memberships=fixture)) res = req.get_response(self.api) self.assertEqual(res.status_int, 204) req = webob.Request.blank('/images/%s/members' % UUID2) req.method = 'GET' res = req.get_response(self.api) self.assertEqual(res.status_int, 200) memb_list = jsonutils.loads(res.body) self.assertEqual(len(memb_list), 1) def test_replace_members_of_image_overlimit(self): # Set image_member_quota to 1 self.config(image_member_quota=1) test_router = router.API(self.mapper) self.api = test_utils.FakeAuthMiddleware(test_router, is_admin=True) # PUT an original member entry fixture = [{'member_id': 'baz', 'can_share': False}] req = webob.Request.blank('/images/%s/members' % UUID2) req.method = 'PUT' req.body = jsonutils.dumps(dict(memberships=fixture)) res = req.get_response(self.api) self.assertEqual(res.status_int, 204) # GET original image member list req = webob.Request.blank('/images/%s/members' % UUID2) req.method = 'GET' res = req.get_response(self.api) self.assertEqual(res.status_int, 200) original_members = jsonutils.loads(res.body)['members'] self.assertEqual(len(original_members), 1) # PUT 2 image members to replace existing (overlimit) fixture = [{'member_id': 'foo1', 'can_share': False}, {'member_id': 'foo2', 'can_share': False}] req = webob.Request.blank('/images/%s/members' % UUID2) req.method = 'PUT' req.body = jsonutils.dumps(dict(memberships=fixture)) res = req.get_response(self.api) self.assertEqual(res.status_int, 413) # GET member list req = webob.Request.blank('/images/%s/members' % UUID2) req.method = 'GET' res = req.get_response(self.api) self.assertEqual(res.status_int, 200) # Assert the member list was not changed memb_list = jsonutils.loads(res.body)['members'] self.assertEqual(memb_list, original_members) def test_replace_members_of_image_unlimited(self): self.config(image_member_quota=-1) test_router = router.API(self.mapper) self.api = test_utils.FakeAuthMiddleware(test_router, is_admin=True) fixture = [{'member_id': 'foo1', 'can_share': False}, {'member_id': 'foo2', 'can_share': False}] req = webob.Request.blank('/images/%s/members' % UUID2) req.method = 'PUT' req.body = jsonutils.dumps(dict(memberships=fixture)) res = req.get_response(self.api) self.assertEqual(res.status_int, 204) req = webob.Request.blank('/images/%s/members' % UUID2) req.method = 'GET' res = req.get_response(self.api) self.assertEqual(res.status_int, 200) memb_list = jsonutils.loads(res.body)['members'] self.assertEqual(memb_list, fixture) def test_create_member_to_deleted_image_raises_404(self): """ Tests adding members to deleted image raises 404. """ test_router = router.API(self.mapper) self.api = test_utils.FakeAuthMiddleware(test_router, is_admin=True) req = webob.Request.blank("/images/%s" % UUID2) req.method = 'DELETE' res = req.get_response(self.api) self.assertEqual(res.status_int, 200) req = webob.Request.blank('/images/%s/members/pattieblack' % UUID2) req.method = 'PUT' res = req.get_response(self.api) self.assertEqual(res.status_int, webob.exc.HTTPNotFound.code) self.assertTrue( 'Image with identifier %s has been deleted.' % UUID2 in res.body) def test_delete_member(self): """ Tests deleting image members raises right exception """ test_router = router.API(self.mapper) self.api = test_utils.FakeAuthMiddleware( test_router, is_admin=False) req = webob.Request.blank('/images/%s/members/pattieblack' % UUID2) req.method = 'DELETE' res = req.get_response(self.api) self.assertEqual(res.status_int, 401) def test_delete_member_on_non_existing_image(self): """ Tests deleting image members raises right exception """ test_router = router.API(self.mapper) api = test_utils.FakeAuthMiddleware(test_router, is_admin=True) test_uri = '/images/%s/members/pattieblack' req = webob.Request.blank(test_uri % _gen_uuid()) req.method = 'DELETE' res = req.get_response(api) self.assertEqual(res.status_int, 404) def test_delete_non_exist_member(self): """ Test deleting image members raises right exception """ test_router = router.API(self.mapper) api = test_utils.FakeAuthMiddleware( test_router, is_admin=True) req = webob.Request.blank('/images/%s/members/test_user' % UUID2) req.method = 'DELETE' res = req.get_response(api) self.assertEqual(res.status_int, 404) def test_delete_image_member(self): test_rserver = router.API(self.mapper) self.api = test_utils.FakeAuthMiddleware( test_rserver, is_admin=True) # Add member to image: fixture = dict(can_share=True) test_uri = '/images/%s/members/test_add_member_positive' req = webob.Request.blank(test_uri % UUID2) req.method = 'PUT' req.content_type = 'application/json' req.body = jsonutils.dumps(dict(member=fixture)) res = req.get_response(self.api) self.assertEqual(res.status_int, 204) # Delete member test_uri = '/images/%s/members/test_add_member_positive' req = webob.Request.blank(test_uri % UUID2) req.headers['X-Auth-Token'] = 'test1:test1:' req.method = 'DELETE' req.content_type = 'application/json' res = req.get_response(self.api) self.assertEqual(res.status_int, 404) self.assertTrue('Forbidden' in res.body) def test_delete_member_allowed_by_policy(self): rules = {"delete_member": '@', "modify_member": '@'} self.set_policy_rules(rules) self.api = test_utils.FakeAuthMiddleware(router.API(self.mapper), is_admin=True) req = webob.Request.blank('/images/%s/members/pattieblack' % UUID2) req.method = 'PUT' res = req.get_response(self.api) self.assertEqual(res.status_int, webob.exc.HTTPNoContent.code) req.method = 'DELETE' res = req.get_response(self.api) self.assertEqual(res.status_int, webob.exc.HTTPNoContent.code) def test_delete_member_forbidden_by_policy(self): rules = {"delete_member": '!', "modify_member": '@'} self.set_policy_rules(rules) self.api = test_utils.FakeAuthMiddleware(router.API(self.mapper), is_admin=True) req = webob.Request.blank('/images/%s/members/pattieblack' % UUID2) req.method = 'PUT' res = req.get_response(self.api) self.assertEqual(res.status_int, webob.exc.HTTPNoContent.code) req.method = 'DELETE' res = req.get_response(self.api) self.assertEqual(res.status_int, webob.exc.HTTPForbidden.code) class TestImageSerializer(base.IsolatedUnitTest): def setUp(self): """Establish a clean test environment""" super(TestImageSerializer, self).setUp() self.receiving_user = 'fake_user' self.receiving_tenant = 2 self.context = glance.context.RequestContext( is_admin=True, user=self.receiving_user, tenant=self.receiving_tenant) self.serializer = glance.api.v1.images.ImageSerializer() def image_iter(): for x in ['chunk', '678911234', '56789']: yield x self.FIXTURE = { 'image_iterator': image_iter(), 'image_meta': { 'id': UUID2, 'name': 'fake image #2', 'status': 'active', 'disk_format': 'vhd', 'container_format': 'ovf', 'is_public': True, 'created_at': timeutils.utcnow(), 'updated_at': timeutils.utcnow(), 'deleted_at': None, 'deleted': False, 'checksum': '06ff575a2856444fbe93100157ed74ab92eb7eff', 'size': 19, 'owner': _gen_uuid(), 'location': "file:///tmp/glance-tests/2", 'properties': {}, } } def test_meta(self): exp_headers = {'x-image-meta-id': UUID2, 'x-image-meta-location': 'file:///tmp/glance-tests/2', 'ETag': self.FIXTURE['image_meta']['checksum'], 'x-image-meta-name': 'fake image #2'} req = webob.Request.blank("/images/%s" % UUID2) req.method = 'HEAD' req.remote_addr = "1.2.3.4" req.context = self.context response = webob.Response(request=req) self.serializer.meta(response, self.FIXTURE) for key, value in exp_headers.iteritems(): self.assertEqual(value, response.headers[key]) def test_meta_utf8(self): # We get unicode strings from JSON, and therefore all strings in the # metadata will actually be unicode when handled internally. But we # want to output utf-8. FIXTURE = { 'image_meta': { 'id': unicode(UUID2), 'name': u'fake image #2 with utf-8 éàè', 'status': u'active', 'disk_format': u'vhd', 'container_format': u'ovf', 'is_public': True, 'created_at': timeutils.utcnow(), 'updated_at': timeutils.utcnow(), 'deleted_at': None, 'deleted': False, 'checksum': u'06ff575a2856444fbe93100157ed74ab92eb7eff', 'size': 19, 'owner': unicode(_gen_uuid()), 'location': u"file:///tmp/glance-tests/2", 'properties': { u'prop_éé': u'ça marche', u'prop_çé': u'çé', } } } exp_headers = {'x-image-meta-id': UUID2.encode('utf-8'), 'x-image-meta-location': 'file:///tmp/glance-tests/2', 'ETag': '06ff575a2856444fbe93100157ed74ab92eb7eff', 'x-image-meta-size': '19', # str, not int 'x-image-meta-name': 'fake image #2 with utf-8 éàè', 'x-image-meta-property-prop_éé': 'ça marche', 'x-image-meta-property-prop_çé': u'çé'.encode('utf-8')} req = webob.Request.blank("/images/%s" % UUID2) req.method = 'HEAD' req.remote_addr = "1.2.3.4" req.context = self.context response = webob.Response(request=req) self.serializer.meta(response, FIXTURE) self.assertNotEqual(type(FIXTURE['image_meta']['name']), type(response.headers['x-image-meta-name'])) self.assertEqual(response.headers['x-image-meta-name'].decode('utf-8'), FIXTURE['image_meta']['name']) for key, value in exp_headers.iteritems(): self.assertEqual(value, response.headers[key]) FIXTURE['image_meta']['properties'][u'prop_bad'] = 'çé' self.assertRaises(UnicodeDecodeError, self.serializer.meta, response, FIXTURE) def test_show(self): exp_headers = {'x-image-meta-id': UUID2, 'x-image-meta-location': 'file:///tmp/glance-tests/2', 'ETag': self.FIXTURE['image_meta']['checksum'], 'x-image-meta-name': 'fake image #2'} req = webob.Request.blank("/images/%s" % UUID2) req.method = 'GET' req.context = self.context response = webob.Response(request=req) self.serializer.show(response, self.FIXTURE) for key, value in exp_headers.iteritems(): self.assertEqual(value, response.headers[key]) self.assertEqual(response.body, 'chunk67891123456789') def test_show_notify(self): """Make sure an eventlet posthook for notify_image_sent is added.""" req = webob.Request.blank("/images/%s" % UUID2) req.method = 'GET' req.context = self.context response = webob.Response(request=req) response.request.environ['eventlet.posthooks'] = [] self.serializer.show(response, self.FIXTURE) #just make sure the app_iter is called for chunk in response.app_iter: pass self.assertNotEqual(response.request.environ['eventlet.posthooks'], []) def test_image_send_notification(self): req = webob.Request.blank("/images/%s" % UUID2) req.method = 'GET' req.remote_addr = '1.2.3.4' req.context = self.context image_meta = self.FIXTURE['image_meta'] called = {"notified": False} expected_payload = { 'bytes_sent': 19, 'image_id': UUID2, 'owner_id': image_meta['owner'], 'receiver_tenant_id': self.receiving_tenant, 'receiver_user_id': self.receiving_user, 'destination_ip': '1.2.3.4', } def fake_info(_event_type, _payload): self.assertEqual(_payload, expected_payload) called['notified'] = True self.stubs.Set(self.serializer.notifier, 'info', fake_info) glance.api.common.image_send_notification(19, 19, image_meta, req, self.serializer.notifier) self.assertTrue(called['notified']) def test_image_send_notification_error(self): """Ensure image.send notification is sent on error.""" req = webob.Request.blank("/images/%s" % UUID2) req.method = 'GET' req.remote_addr = '1.2.3.4' req.context = self.context image_meta = self.FIXTURE['image_meta'] called = {"notified": False} expected_payload = { 'bytes_sent': 17, 'image_id': UUID2, 'owner_id': image_meta['owner'], 'receiver_tenant_id': self.receiving_tenant, 'receiver_user_id': self.receiving_user, 'destination_ip': '1.2.3.4', } def fake_error(_event_type, _payload): self.assertEqual(_payload, expected_payload) called['notified'] = True self.stubs.Set(self.serializer.notifier, 'error', fake_error) #expected and actually sent bytes differ glance.api.common.image_send_notification(17, 19, image_meta, req, self.serializer.notifier) self.assertTrue(called['notified']) def test_redact_location(self): """Ensure location redaction does not change original metadata""" image_meta = {'size': 3, 'id': '123', 'location': 'http://localhost'} redacted_image_meta = {'size': 3, 'id': '123'} copy_image_meta = copy.deepcopy(image_meta) tmp_image_meta = glance.api.v1.images.redact_loc(image_meta) self.assertEqual(image_meta, copy_image_meta) self.assertEqual(tmp_image_meta, redacted_image_meta) def test_noop_redact_location(self): """Check no-op location redaction does not change original metadata""" image_meta = {'size': 3, 'id': '123'} redacted_image_meta = {'size': 3, 'id': '123'} copy_image_meta = copy.deepcopy(image_meta) tmp_image_meta = glance.api.v1.images.redact_loc(image_meta) self.assertEqual(image_meta, copy_image_meta) self.assertEqual(tmp_image_meta, redacted_image_meta) self.assertEqual(image_meta, redacted_image_meta) class TestFilterValidator(base.IsolatedUnitTest): def test_filter_validator(self): self.assertFalse(glance.api.v1.filters.validate('size_max', -1)) self.assertTrue(glance.api.v1.filters.validate('size_max', 1)) self.assertTrue(glance.api.v1.filters.validate('protected', 'True')) self.assertTrue(glance.api.v1.filters.validate('protected', 'FALSE')) self.assertFalse(glance.api.v1.filters.validate('protected', '-1')) class TestAPIProtectedProps(base.IsolatedUnitTest): def setUp(self): """Establish a clean test environment""" super(TestAPIProtectedProps, self).setUp() self.mapper = routes.Mapper() # turn on property protections self.set_property_protections() self.api = test_utils.FakeAuthMiddleware(router.API(self.mapper)) db_api.get_engine() db_models.unregister_models(db_api.get_engine()) db_models.register_models(db_api.get_engine()) def tearDown(self): """Clear the test environment""" super(TestAPIProtectedProps, self).tearDown() self.destroy_fixtures() def destroy_fixtures(self): # Easiest to just drop the models and re-create them... db_models.unregister_models(db_api.get_engine()) db_models.register_models(db_api.get_engine()) def _create_admin_image(self, props={}): request = unit_test_utils.get_fake_request(path='/images') headers = {'x-image-meta-disk-format': 'ami', 'x-image-meta-container-format': 'ami', 'x-image-meta-name': 'foo', 'x-image-meta-size': '0', 'x-auth-token': 'user:tenant:admin'} headers.update(props) for k, v in headers.iteritems(): request.headers[k] = v created_image = request.get_response(self.api) res_body = jsonutils.loads(created_image.body)['image'] image_id = res_body['id'] return image_id def test_prop_protection_with_create_and_permitted_role(self): """ As admin role, create an image and verify permitted role 'member' can create a protected property """ image_id = self._create_admin_image() another_request = unit_test_utils.get_fake_request( path='/images/%s' % image_id, method='PUT') headers = {'x-auth-token': 'user:tenant:member', 'x-image-meta-property-x_owner_foo': 'bar'} for k, v in headers.iteritems(): another_request.headers[k] = v output = another_request.get_response(self.api) res_body = jsonutils.loads(output.body)['image'] self.assertEqual(res_body['properties']['x_owner_foo'], 'bar') def test_prop_protection_with_permitted_policy_config(self): """ As admin role, create an image and verify permitted role 'member' can create a protected property """ self.set_property_protections(use_policies=True) image_id = self._create_admin_image() another_request = unit_test_utils.get_fake_request( path='/images/%s' % image_id, method='PUT') headers = {'x-auth-token': 'user:tenant:admin', 'x-image-meta-property-spl_create_prop_policy': 'bar'} for k, v in headers.iteritems(): another_request.headers[k] = v output = another_request.get_response(self.api) self.assertEqual(output.status_int, 200) res_body = jsonutils.loads(output.body)['image'] self.assertEqual(res_body['properties']['spl_create_prop_policy'], 'bar') def test_prop_protection_with_create_and_unpermitted_role(self): """ As admin role, create an image and verify unpermitted role 'fake_member' can *not* create a protected property """ image_id = self._create_admin_image() another_request = unit_test_utils.get_fake_request( path='/images/%s' % image_id, method='PUT') headers = {'x-auth-token': 'user:tenant:fake_member', 'x-image-meta-property-x_owner_foo': 'bar'} for k, v in headers.iteritems(): another_request.headers[k] = v another_request.get_response(self.api) output = another_request.get_response(self.api) self.assertEqual(output.status_int, webob.exc.HTTPForbidden.code) self.assertIn("Property '%s' is protected" % "x_owner_foo", output.body) def test_prop_protection_with_show_and_permitted_role(self): """ As admin role, create an image with a protected property, and verify permitted role 'member' can read that protected property via HEAD """ image_id = self._create_admin_image( {'x-image-meta-property-x_owner_foo': 'bar'}) another_request = unit_test_utils.get_fake_request( method='HEAD', path='/images/%s' % image_id) headers = {'x-auth-token': 'user:tenant:member'} for k, v in headers.iteritems(): another_request.headers[k] = v res2 = another_request.get_response(self.api) self.assertEqual(res2.headers['x-image-meta-property-x_owner_foo'], 'bar') def test_prop_protection_with_show_and_unpermitted_role(self): """ As admin role, create an image with a protected property, and verify permitted role 'fake_role' can *not* read that protected property via HEAD """ image_id = self._create_admin_image( {'x-image-meta-property-x_owner_foo': 'bar'}) another_request = unit_test_utils.get_fake_request( method='HEAD', path='/images/%s' % image_id) headers = {'x-auth-token': 'user:tenant:fake_role'} for k, v in headers.iteritems(): another_request.headers[k] = v output = another_request.get_response(self.api) self.assertEqual(output.status_int, 200) self.assertEqual('', output.body) self.assertNotIn('x-image-meta-property-x_owner_foo', output.headers) def test_prop_protection_with_get_and_permitted_role(self): """ As admin role, create an image with a protected property, and verify permitted role 'member' can read that protected property via GET """ image_id = self._create_admin_image( {'x-image-meta-property-x_owner_foo': 'bar'}) another_request = unit_test_utils.get_fake_request( method='GET', path='/images/%s' % image_id) headers = {'x-auth-token': 'user:tenant:member'} for k, v in headers.iteritems(): another_request.headers[k] = v res2 = another_request.get_response(self.api) self.assertEqual(res2.headers['x-image-meta-property-x_owner_foo'], 'bar') def test_prop_protection_with_get_and_unpermitted_role(self): """ As admin role, create an image with a protected property, and verify permitted role 'fake_role' can *not* read that protected property via GET """ image_id = self._create_admin_image( {'x-image-meta-property-x_owner_foo': 'bar'}) another_request = unit_test_utils.get_fake_request( method='GET', path='/images/%s' % image_id) headers = {'x-auth-token': 'user:tenant:fake_role'} for k, v in headers.iteritems(): another_request.headers[k] = v output = another_request.get_response(self.api) self.assertEqual(output.status_int, 200) self.assertEqual('', output.body) self.assertNotIn('x-image-meta-property-x_owner_foo', output.headers) def test_prop_protection_with_detail_and_permitted_role(self): """ As admin role, create an image with a protected property, and verify permitted role 'member' can read that protected property via /images/detail """ self._create_admin_image({'x-image-meta-property-x_owner_foo': 'bar'}) another_request = unit_test_utils.get_fake_request( method='GET', path='/images/detail') headers = {'x-auth-token': 'user:tenant:member'} for k, v in headers.iteritems(): another_request.headers[k] = v output = another_request.get_response(self.api) self.assertEqual(output.status_int, 200) res_body = jsonutils.loads(output.body)['images'][0] self.assertEqual(res_body['properties']['x_owner_foo'], 'bar') def test_prop_protection_with_detail_and_permitted_policy(self): """ As admin role, create an image with a protected property, and verify permitted role 'member' can read that protected property via /images/detail """ self.set_property_protections(use_policies=True) self._create_admin_image({'x-image-meta-property-x_owner_foo': 'bar'}) another_request = unit_test_utils.get_fake_request( method='GET', path='/images/detail') headers = {'x-auth-token': 'user:tenant:member'} for k, v in headers.iteritems(): another_request.headers[k] = v output = another_request.get_response(self.api) self.assertEqual(output.status_int, 200) res_body = jsonutils.loads(output.body)['images'][0] self.assertEqual(res_body['properties']['x_owner_foo'], 'bar') def test_prop_protection_with_detail_and_unpermitted_role(self): """ As admin role, create an image with a protected property, and verify permitted role 'fake_role' can *not* read that protected property via /images/detail """ self._create_admin_image({'x-image-meta-property-x_owner_foo': 'bar'}) another_request = unit_test_utils.get_fake_request( method='GET', path='/images/detail') headers = {'x-auth-token': 'user:tenant:fake_role'} for k, v in headers.iteritems(): another_request.headers[k] = v output = another_request.get_response(self.api) self.assertEqual(output.status_int, 200) res_body = jsonutils.loads(output.body)['images'][0] self.assertNotIn('x-image-meta-property-x_owner_foo', res_body['properties']) def test_prop_protection_with_detail_and_unpermitted_policy(self): """ As admin role, create an image with a protected property, and verify permitted role 'fake_role' can *not* read that protected property via /images/detail """ self.set_property_protections(use_policies=True) self._create_admin_image({'x-image-meta-property-x_owner_foo': 'bar'}) another_request = unit_test_utils.get_fake_request( method='GET', path='/images/detail') headers = {'x-auth-token': 'user:tenant:fake_role'} for k, v in headers.iteritems(): another_request.headers[k] = v output = another_request.get_response(self.api) self.assertEqual(output.status_int, 200) res_body = jsonutils.loads(output.body)['images'][0] self.assertNotIn('x-image-meta-property-x_owner_foo', res_body['properties']) def test_prop_protection_with_update_and_permitted_role(self): """ As admin role, create an image with protected property, and verify permitted role 'member' can update that protected property """ image_id = self._create_admin_image( {'x-image-meta-property-x_owner_foo': 'bar'}) another_request = unit_test_utils.get_fake_request( path='/images/%s' % image_id, method='PUT') headers = {'x-auth-token': 'user:tenant:member', 'x-image-meta-property-x_owner_foo': 'baz'} for k, v in headers.iteritems(): another_request.headers[k] = v output = another_request.get_response(self.api) res_body = jsonutils.loads(output.body)['image'] self.assertEqual(res_body['properties']['x_owner_foo'], 'baz') def test_prop_protection_with_update_and_permitted_policy(self): """ As admin role, create an image with protected property, and verify permitted role 'admin' can update that protected property """ self.set_property_protections(use_policies=True) image_id = self._create_admin_image( {'x-image-meta-property-spl_default_policy': 'bar'}) another_request = unit_test_utils.get_fake_request( path='/images/%s' % image_id, method='PUT') headers = {'x-auth-token': 'user:tenant:admin', 'x-image-meta-property-spl_default_policy': 'baz'} for k, v in headers.iteritems(): another_request.headers[k] = v output = another_request.get_response(self.api) res_body = jsonutils.loads(output.body)['image'] self.assertEqual(res_body['properties']['spl_default_policy'], 'baz') def test_prop_protection_with_update_and_unpermitted_role(self): """ As admin role, create an image with protected property, and verify unpermitted role 'fake_role' can *not* update that protected property """ image_id = self._create_admin_image( {'x-image-meta-property-x_owner_foo': 'bar'}) another_request = unit_test_utils.get_fake_request( path='/images/%s' % image_id, method='PUT') headers = {'x-auth-token': 'user:tenant:fake_role', 'x-image-meta-property-x_owner_foo': 'baz'} for k, v in headers.iteritems(): another_request.headers[k] = v output = another_request.get_response(self.api) self.assertEqual(output.status_int, webob.exc.HTTPForbidden.code) self.assertIn("Property '%s' is protected" % "x_owner_foo", output.body) def test_prop_protection_with_update_and_unpermitted_policy(self): """ As admin role, create an image with protected property, and verify unpermitted role 'fake_role' can *not* update that protected property """ self.set_property_protections(use_policies=True) image_id = self._create_admin_image( {'x-image-meta-property-x_owner_foo': 'bar'}) another_request = unit_test_utils.get_fake_request( path='/images/%s' % image_id, method='PUT') headers = {'x-auth-token': 'user:tenant:fake_role', 'x-image-meta-property-x_owner_foo': 'baz'} for k, v in headers.iteritems(): another_request.headers[k] = v output = another_request.get_response(self.api) self.assertEqual(output.status_int, webob.exc.HTTPForbidden.code) self.assertIn("Property '%s' is protected" % "x_owner_foo", output.body) def test_prop_protection_update_without_read(self): """ Test protected property cannot be updated without read permission """ image_id = self._create_admin_image( {'x-image-meta-property-spl_update_only_prop': 'foo'}) another_request = unit_test_utils.get_fake_request( path='/images/%s' % image_id, method='PUT') headers = {'x-auth-token': 'user:tenant:spl_role', 'x-image-meta-property-spl_update_only_prop': 'bar'} for k, v in headers.iteritems(): another_request.headers[k] = v output = another_request.get_response(self.api) self.assertEqual(output.status_int, webob.exc.HTTPForbidden.code) self.assertIn("Property '%s' is protected" % "spl_update_only_prop", output.body) def test_prop_protection_update_noop(self): """ Test protected property update is allowed as long as the user has read access and the value is unchanged """ image_id = self._create_admin_image( {'x-image-meta-property-spl_read_prop': 'foo'}) another_request = unit_test_utils.get_fake_request( path='/images/%s' % image_id, method='PUT') headers = {'x-auth-token': 'user:tenant:spl_role', 'x-image-meta-property-spl_read_prop': 'foo'} for k, v in headers.iteritems(): another_request.headers[k] = v output = another_request.get_response(self.api) res_body = jsonutils.loads(output.body)['image'] self.assertEqual(res_body['properties']['spl_read_prop'], 'foo') self.assertEqual(output.status_int, 200) def test_prop_protection_with_delete_and_permitted_role(self): """ As admin role, create an image with protected property, and verify permitted role 'member' can can delete that protected property """ image_id = self._create_admin_image( {'x-image-meta-property-x_owner_foo': 'bar'}) another_request = unit_test_utils.get_fake_request( path='/images/%s' % image_id, method='PUT') headers = {'x-auth-token': 'user:tenant:member', 'X-Glance-Registry-Purge-Props': 'True'} for k, v in headers.iteritems(): another_request.headers[k] = v output = another_request.get_response(self.api) res_body = jsonutils.loads(output.body)['image'] self.assertEqual(res_body['properties'], {}) def test_prop_protection_with_delete_and_permitted_policy(self): """ As admin role, create an image with protected property, and verify permitted role 'member' can can delete that protected property """ self.set_property_protections(use_policies=True) image_id = self._create_admin_image( {'x-image-meta-property-x_owner_foo': 'bar'}) another_request = unit_test_utils.get_fake_request( path='/images/%s' % image_id, method='PUT') headers = {'x-auth-token': 'user:tenant:member', 'X-Glance-Registry-Purge-Props': 'True'} for k, v in headers.iteritems(): another_request.headers[k] = v output = another_request.get_response(self.api) res_body = jsonutils.loads(output.body)['image'] self.assertEqual(res_body['properties'], {}) def test_prop_protection_with_delete_and_unpermitted_read(self): """ Test protected property cannot be deleted without read permission """ image_id = self._create_admin_image( {'x-image-meta-property-x_owner_foo': 'bar'}) another_request = unit_test_utils.get_fake_request( path='/images/%s' % image_id, method='PUT') headers = {'x-auth-token': 'user:tenant:fake_role', 'X-Glance-Registry-Purge-Props': 'True'} for k, v in headers.iteritems(): another_request.headers[k] = v output = another_request.get_response(self.api) self.assertEqual(output.status_int, 200) self.assertNotIn('x-image-meta-property-x_owner_foo', output.headers) another_request = unit_test_utils.get_fake_request( method='HEAD', path='/images/%s' % image_id) headers = {'x-auth-token': 'user:tenant:admin'} for k, v in headers.iteritems(): another_request.headers[k] = v output = another_request.get_response(self.api) self.assertEqual(output.status_int, 200) self.assertEqual('', output.body) self.assertEqual(output.headers['x-image-meta-property-x_owner_foo'], 'bar') def test_prop_protection_with_delete_and_unpermitted_delete(self): """ Test protected property cannot be deleted without delete permission """ image_id = self._create_admin_image( {'x-image-meta-property-spl_update_prop': 'foo'}) another_request = unit_test_utils.get_fake_request( path='/images/%s' % image_id, method='PUT') headers = {'x-auth-token': 'user:tenant:spl_role', 'X-Glance-Registry-Purge-Props': 'True'} for k, v in headers.iteritems(): another_request.headers[k] = v output = another_request.get_response(self.api) self.assertEqual(output.status_int, 403) self.assertIn("Property '%s' is protected" % "spl_update_prop", output.body) another_request = unit_test_utils.get_fake_request( method='HEAD', path='/images/%s' % image_id) headers = {'x-auth-token': 'user:tenant:admin'} for k, v in headers.iteritems(): another_request.headers[k] = v output = another_request.get_response(self.api) self.assertEqual(output.status_int, 200) self.assertEqual('', output.body) self.assertEqual( output.headers['x-image-meta-property-spl_update_prop'], 'foo') def test_read_protected_props_leak_with_update(self): """ Verify when updating props that ones we don't have read permission for are not disclosed """ image_id = self._create_admin_image( {'x-image-meta-property-spl_update_prop': '0', 'x-image-meta-property-foo': 'bar'}) another_request = unit_test_utils.get_fake_request( path='/images/%s' % image_id, method='PUT') headers = {'x-auth-token': 'user:tenant:spl_role', 'x-image-meta-property-spl_update_prop': '1', 'X-Glance-Registry-Purge-Props': 'False'} for k, v in headers.iteritems(): another_request.headers[k] = v output = another_request.get_response(self.api) res_body = jsonutils.loads(output.body)['image'] self.assertEqual(res_body['properties']['spl_update_prop'], '1') self.assertNotIn('foo', res_body['properties']) def test_update_protected_props_mix_no_read(self): """ Create an image with two props - one only readable by admin, and one readable/updatable by member. Verify member can successfully update their property while the admin owned one is ignored transparently """ image_id = self._create_admin_image( {'x-image-meta-property-admin_foo': 'bar', 'x-image-meta-property-x_owner_foo': 'bar'}) another_request = unit_test_utils.get_fake_request( path='/images/%s' % image_id, method='PUT') headers = {'x-auth-token': 'user:tenant:member', 'x-image-meta-property-x_owner_foo': 'baz'} for k, v in headers.iteritems(): another_request.headers[k] = v output = another_request.get_response(self.api) res_body = jsonutils.loads(output.body)['image'] self.assertEqual(res_body['properties']['x_owner_foo'], 'baz') self.assertNotIn('admin_foo', res_body['properties']) def test_update_protected_props_mix_read(self): """ Create an image with two props - one readable/updatable by admin, but also readable by spl_role. The other is readable/updatable by spl_role. Verify spl_role can successfully update their property but not the admin owned one """ custom_props = { 'x-image-meta-property-spl_read_only_prop': '1', 'x-image-meta-property-spl_update_prop': '2' } image_id = self._create_admin_image(custom_props) another_request = unit_test_utils.get_fake_request( path='/images/%s' % image_id, method='PUT') # verify spl_role can update it's prop headers = {'x-auth-token': 'user:tenant:spl_role', 'x-image-meta-property-spl_read_only_prop': '1', 'x-image-meta-property-spl_update_prop': '1'} for k, v in headers.iteritems(): another_request.headers[k] = v output = another_request.get_response(self.api) res_body = jsonutils.loads(output.body)['image'] self.assertEqual(output.status_int, 200) self.assertEqual(res_body['properties']['spl_read_only_prop'], '1') self.assertEqual(res_body['properties']['spl_update_prop'], '1') # verify spl_role can not update admin controlled prop headers = {'x-auth-token': 'user:tenant:spl_role', 'x-image-meta-property-spl_read_only_prop': '2', 'x-image-meta-property-spl_update_prop': '1'} for k, v in headers.iteritems(): another_request.headers[k] = v output = another_request.get_response(self.api) self.assertEqual(output.status_int, 403) def test_delete_protected_props_mix_no_read(self): """ Create an image with two props - one only readable by admin, and one readable/deletable by member. Verify member can successfully delete their property while the admin owned one is ignored transparently """ image_id = self._create_admin_image( {'x-image-meta-property-admin_foo': 'bar', 'x-image-meta-property-x_owner_foo': 'bar'}) another_request = unit_test_utils.get_fake_request( path='/images/%s' % image_id, method='PUT') headers = {'x-auth-token': 'user:tenant:member', 'X-Glance-Registry-Purge-Props': 'True'} for k, v in headers.iteritems(): another_request.headers[k] = v output = another_request.get_response(self.api) res_body = jsonutils.loads(output.body)['image'] self.assertNotIn('x_owner_foo', res_body['properties']) self.assertNotIn('admin_foo', res_body['properties']) def test_delete_protected_props_mix_read(self): """ Create an image with two props - one readable/deletable by admin, but also readable by spl_role. The other is readable/deletable by spl_role. Verify spl_role is forbidden to purge_props in this scenario without retaining the readable prop. """ custom_props = { 'x-image-meta-property-spl_read_only_prop': '1', 'x-image-meta-property-spl_delete_prop': '2' } image_id = self._create_admin_image(custom_props) another_request = unit_test_utils.get_fake_request( path='/images/%s' % image_id, method='PUT') headers = {'x-auth-token': 'user:tenant:spl_role', 'X-Glance-Registry-Purge-Props': 'True'} for k, v in headers.iteritems(): another_request.headers[k] = v output = another_request.get_response(self.api) self.assertEqual(output.status_int, 403) def test_create_non_protected_prop(self): """ Verify property marked with special char '@' is creatable by an unknown role """ image_id = self._create_admin_image() another_request = unit_test_utils.get_fake_request( path='/images/%s' % image_id, method='PUT') headers = {'x-auth-token': 'user:tenant:joe_soap', 'x-image-meta-property-x_all_permitted': '1'} for k, v in headers.iteritems(): another_request.headers[k] = v output = another_request.get_response(self.api) res_body = jsonutils.loads(output.body)['image'] self.assertEqual(res_body['properties']['x_all_permitted'], '1') def test_read_non_protected_prop(self): """ Verify property marked with special char '@' is readable by an unknown role """ custom_props = { 'x-image-meta-property-x_all_permitted': '1' } image_id = self._create_admin_image(custom_props) another_request = unit_test_utils.get_fake_request( method='HEAD', path='/images/%s' % image_id) headers = {'x-auth-token': 'user:tenant:joe_soap'} for k, v in headers.iteritems(): another_request.headers[k] = v output = another_request.get_response(self.api) self.assertEqual(output.status_int, 200) self.assertEqual('', output.body) self.assertEqual( output.headers['x-image-meta-property-x_all_permitted'], '1') def test_update_non_protected_prop(self): """ Verify property marked with special char '@' is updatable by an unknown role """ image_id = self._create_admin_image( {'x-image-meta-property-x_all_permitted': '1'}) another_request = unit_test_utils.get_fake_request( path='/images/%s' % image_id, method='PUT') headers = {'x-auth-token': 'user:tenant:joe_soap', 'x-image-meta-property-x_all_permitted': '2'} for k, v in headers.iteritems(): another_request.headers[k] = v output = another_request.get_response(self.api) res_body = jsonutils.loads(output.body)['image'] self.assertEqual(res_body['properties']['x_all_permitted'], '2') def test_delete_non_protected_prop(self): """ Verify property marked with special char '@' is deletable by an unknown role """ image_id = self._create_admin_image( {'x-image-meta-property-x_all_permitted': '1'}) another_request = unit_test_utils.get_fake_request( path='/images/%s' % image_id, method='PUT') headers = {'x-auth-token': 'user:tenant:joe_soap', 'X-Glance-Registry-Purge-Props': 'True'} for k, v in headers.iteritems(): another_request.headers[k] = v output = another_request.get_response(self.api) res_body = jsonutils.loads(output.body)['image'] self.assertEqual(res_body['properties'], {}) def test_create_locked_down_protected_prop(self): """ Verify a property protected by special char '!' is creatable by no one """ image_id = self._create_admin_image() another_request = unit_test_utils.get_fake_request( path='/images/%s' % image_id, method='PUT') headers = {'x-auth-token': 'user:tenant:member', 'x-image-meta-property-x_none_permitted': '1'} for k, v in headers.iteritems(): another_request.headers[k] = v output = another_request.get_response(self.api) self.assertEqual(output.status_int, 403) # also check admin can not create another_request = unit_test_utils.get_fake_request( path='/images/%s' % image_id, method='PUT') headers = {'x-auth-token': 'user:tenant:admin', 'x-image-meta-property-x_none_permitted_admin': '1'} for k, v in headers.iteritems(): another_request.headers[k] = v output = another_request.get_response(self.api) self.assertEqual(output.status_int, 403) def test_read_locked_down_protected_prop(self): """ Verify a property protected by special char '!' is readable by no one """ custom_props = { 'x-image-meta-property-x_none_read': '1' } image_id = self._create_admin_image(custom_props) another_request = unit_test_utils.get_fake_request( method='HEAD', path='/images/%s' % image_id) headers = {'x-auth-token': 'user:tenant:member'} for k, v in headers.iteritems(): another_request.headers[k] = v output = another_request.get_response(self.api) self.assertEqual(output.status_int, 200) self.assertNotIn('x_none_read', output.headers) # also check admin can not read another_request = unit_test_utils.get_fake_request( method='HEAD', path='/images/%s' % image_id) headers = {'x-auth-token': 'user:tenant:admin'} for k, v in headers.iteritems(): another_request.headers[k] = v output = another_request.get_response(self.api) self.assertEqual(output.status_int, 200) self.assertNotIn('x_none_read', output.headers) def test_update_locked_down_protected_prop(self): """ Verify a property protected by special char '!' is updatable by no one """ image_id = self._create_admin_image( {'x-image-meta-property-x_none_update': '1'}) another_request = unit_test_utils.get_fake_request( path='/images/%s' % image_id, method='PUT') headers = {'x-auth-token': 'user:tenant:member', 'x-image-meta-property-x_none_update': '2'} for k, v in headers.iteritems(): another_request.headers[k] = v output = another_request.get_response(self.api) self.assertEqual(output.status_int, 403) # also check admin can't update property another_request = unit_test_utils.get_fake_request( path='/images/%s' % image_id, method='PUT') headers = {'x-auth-token': 'user:tenant:admin', 'x-image-meta-property-x_none_update': '2'} for k, v in headers.iteritems(): another_request.headers[k] = v output = another_request.get_response(self.api) self.assertEqual(output.status_int, 403) def test_delete_locked_down_protected_prop(self): """ Verify a property protected by special char '!' is deletable by no one """ image_id = self._create_admin_image( {'x-image-meta-property-x_none_delete': '1'}) another_request = unit_test_utils.get_fake_request( path='/images/%s' % image_id, method='PUT') headers = {'x-auth-token': 'user:tenant:member', 'X-Glance-Registry-Purge-Props': 'True'} for k, v in headers.iteritems(): another_request.headers[k] = v output = another_request.get_response(self.api) self.assertEqual(output.status_int, 403) # also check admin can't delete another_request = unit_test_utils.get_fake_request( path='/images/%s' % image_id, method='PUT') headers = {'x-auth-token': 'user:tenant:admin', 'X-Glance-Registry-Purge-Props': 'True'} for k, v in headers.iteritems(): another_request.headers[k] = v output = another_request.get_response(self.api) self.assertEqual(output.status_int, 403) class TestAPIPropertyQuotas(base.IsolatedUnitTest): def setUp(self): """Establish a clean test environment""" super(TestAPIPropertyQuotas, self).setUp() self.mapper = routes.Mapper() self.api = test_utils.FakeAuthMiddleware(router.API(self.mapper)) db_api.get_engine() db_models.unregister_models(db_api.get_engine()) db_models.register_models(db_api.get_engine()) def _create_admin_image(self, props={}): request = unit_test_utils.get_fake_request(path='/images') headers = {'x-image-meta-disk-format': 'ami', 'x-image-meta-container-format': 'ami', 'x-image-meta-name': 'foo', 'x-image-meta-size': '0', 'x-auth-token': 'user:tenant:admin'} headers.update(props) for k, v in headers.iteritems(): request.headers[k] = v created_image = request.get_response(self.api) res_body = jsonutils.loads(created_image.body)['image'] image_id = res_body['id'] return image_id def test_update_image_with_too_many_properties(self): """ Ensure that updating image properties enforces the quota. """ self.config(image_property_quota=1) image_id = self._create_admin_image() another_request = unit_test_utils.get_fake_request( path='/images/%s' % image_id, method='PUT') headers = {'x-auth-token': 'user:tenant:joe_soap', 'x-image-meta-property-x_all_permitted': '1', 'x-image-meta-property-x_all_permitted_foo': '2'} for k, v in headers.iteritems(): another_request.headers[k] = v output = another_request.get_response(self.api) self.assertEqual(output.status_int, 413) self.assertTrue("Attempted: 2, Maximum: 1" in output.text) def test_update_image_with_too_many_properties_without_purge_props(self): """ Ensure that updating image properties counts existing image propertys when enforcing property quota. """ self.config(image_property_quota=1) request = unit_test_utils.get_fake_request(path='/images') headers = {'x-image-meta-disk-format': 'ami', 'x-image-meta-container-format': 'ami', 'x-image-meta-name': 'foo', 'x-image-meta-size': '0', 'x-image-meta-property-x_all_permitted_create': '1', 'x-auth-token': 'user:tenant:admin'} for k, v in headers.iteritems(): request.headers[k] = v created_image = request.get_response(self.api) res_body = jsonutils.loads(created_image.body)['image'] image_id = res_body['id'] another_request = unit_test_utils.get_fake_request( path='/images/%s' % image_id, method='PUT') headers = {'x-auth-token': 'user:tenant:joe_soap', 'x-glance-registry-purge-props': 'False', 'x-image-meta-property-x_all_permitted': '1'} for k, v in headers.iteritems(): another_request.headers[k] = v output = another_request.get_response(self.api) self.assertEqual(output.status_int, 413) self.assertTrue("Attempted: 2, Maximum: 1" in output.text) def test_update_properties_without_purge_props_overwrite_value(self): """ Ensure that updating image properties does not count against image property quota. """ self.config(image_property_quota=2) request = unit_test_utils.get_fake_request(path='/images') headers = {'x-image-meta-disk-format': 'ami', 'x-image-meta-container-format': 'ami', 'x-image-meta-name': 'foo', 'x-image-meta-size': '0', 'x-image-meta-property-x_all_permitted_create': '1', 'x-auth-token': 'user:tenant:admin'} for k, v in headers.iteritems(): request.headers[k] = v created_image = request.get_response(self.api) res_body = jsonutils.loads(created_image.body)['image'] image_id = res_body['id'] another_request = unit_test_utils.get_fake_request( path='/images/%s' % image_id, method='PUT') headers = {'x-auth-token': 'user:tenant:joe_soap', 'x-glance-registry-purge-props': 'False', 'x-image-meta-property-x_all_permitted_create': '3', 'x-image-meta-property-x_all_permitted': '1'} for k, v in headers.iteritems(): another_request.headers[k] = v output = another_request.get_response(self.api) self.assertEqual(output.status_int, 200) res_body = jsonutils.loads(output.body)['image'] self.assertEqual(res_body['properties']['x_all_permitted'], '1') self.assertEqual(res_body['properties']['x_all_permitted_create'], '3') glance-2014.1/glance/tests/unit/v1/__init__.py0000664000175400017540000000000012323736226022175 0ustar jenkinsjenkins00000000000000glance-2014.1/glance/tests/unit/test_image_cache.py0000664000175400017540000005134712323736226023400 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from contextlib import contextmanager import datetime import hashlib import os import tempfile import time import fixtures import six from six.moves import xrange import stubout from glance.common import exception from glance import image_cache from glance.openstack.common import units #NOTE(bcwaldon): This is imported to load the registry config options import glance.registry # noqa import glance.store.filesystem as fs_store import glance.store.s3 as s3_store from glance.tests import utils as test_utils from glance.tests.utils import skip_if_disabled from glance.tests.utils import xattr_writes_supported FIXTURE_LENGTH = 1024 FIXTURE_DATA = '*' * FIXTURE_LENGTH class ImageCacheTestCase(object): def _setup_fixture_file(self): FIXTURE_FILE = six.StringIO(FIXTURE_DATA) self.assertFalse(self.cache.is_cached(1)) self.assertTrue(self.cache.cache_image_file(1, FIXTURE_FILE)) self.assertTrue(self.cache.is_cached(1)) @skip_if_disabled def test_is_cached(self): """Verify is_cached(1) returns 0, then add something to the cache and verify is_cached(1) returns 1. """ self._setup_fixture_file() @skip_if_disabled def test_read(self): """Verify is_cached(1) returns 0, then add something to the cache and verify after a subsequent read from the cache that is_cached(1) returns 1. """ self._setup_fixture_file() buff = six.StringIO() with self.cache.open_for_read(1) as cache_file: for chunk in cache_file: buff.write(chunk) self.assertEqual(FIXTURE_DATA, buff.getvalue()) @skip_if_disabled def test_open_for_read(self): """Test convenience wrapper for opening a cache file via its image identifier. """ self._setup_fixture_file() buff = six.StringIO() with self.cache.open_for_read(1) as cache_file: for chunk in cache_file: buff.write(chunk) self.assertEqual(FIXTURE_DATA, buff.getvalue()) @skip_if_disabled def test_get_image_size(self): """Test convenience wrapper for querying cache file size via its image identifier. """ self._setup_fixture_file() size = self.cache.get_image_size(1) self.assertEqual(FIXTURE_LENGTH, size) @skip_if_disabled def test_delete(self): """Test delete method that removes an image from the cache.""" self._setup_fixture_file() self.cache.delete_cached_image(1) self.assertFalse(self.cache.is_cached(1)) @skip_if_disabled def test_delete_all(self): """Test delete method that removes an image from the cache.""" for image_id in (1, 2): self.assertFalse(self.cache.is_cached(image_id)) for image_id in (1, 2): FIXTURE_FILE = six.StringIO(FIXTURE_DATA) self.assertTrue(self.cache.cache_image_file(image_id, FIXTURE_FILE)) for image_id in (1, 2): self.assertTrue(self.cache.is_cached(image_id)) self.cache.delete_all_cached_images() for image_id in (1, 2): self.assertFalse(self.cache.is_cached(image_id)) @skip_if_disabled def test_clean_stalled(self): """Test the clean method removes expected images.""" incomplete_file_path = os.path.join(self.cache_dir, 'incomplete', '1') incomplete_file = open(incomplete_file_path, 'w') incomplete_file.write(FIXTURE_DATA) incomplete_file.close() self.assertTrue(os.path.exists(incomplete_file_path)) self.cache.clean(stall_time=0) self.assertFalse(os.path.exists(incomplete_file_path)) @skip_if_disabled def test_clean_stalled_nonzero_stall_time(self): """ Test the clean method removes the stalled images as expected """ incomplete_file_path_1 = os.path.join(self.cache_dir, 'incomplete', '1') incomplete_file_path_2 = os.path.join(self.cache_dir, 'incomplete', '2') for f in (incomplete_file_path_1, incomplete_file_path_2): incomplete_file = open(f, 'w') incomplete_file.write(FIXTURE_DATA) incomplete_file.close() mtime = os.path.getmtime(incomplete_file_path_1) pastday = datetime.datetime.fromtimestamp(mtime) - \ datetime.timedelta(days=1) atime = int(time.mktime(pastday.timetuple())) mtime = atime os.utime(incomplete_file_path_1, (atime, mtime)) self.assertTrue(os.path.exists(incomplete_file_path_1)) self.assertTrue(os.path.exists(incomplete_file_path_2)) self.cache.clean(stall_time=3600) self.assertFalse(os.path.exists(incomplete_file_path_1)) self.assertTrue(os.path.exists(incomplete_file_path_2)) @skip_if_disabled def test_prune(self): """ Test that pruning the cache works as expected... """ self.assertEqual(0, self.cache.get_cache_size()) # Add a bunch of images to the cache. The max cache # size for the cache is set to 5KB and each image is # 1K. We add 10 images to the cache and then we'll # prune it. We should see only 5 images left after # pruning, and the images that are least recently accessed # should be the ones pruned... for x in xrange(10): FIXTURE_FILE = six.StringIO(FIXTURE_DATA) self.assertTrue(self.cache.cache_image_file(x, FIXTURE_FILE)) self.assertEqual(10 * units.Ki, self.cache.get_cache_size()) # OK, hit the images that are now cached... for x in xrange(10): buff = six.StringIO() with self.cache.open_for_read(x) as cache_file: for chunk in cache_file: buff.write(chunk) self.cache.prune() self.assertEqual(5 * units.Ki, self.cache.get_cache_size()) for x in xrange(0, 5): self.assertFalse(self.cache.is_cached(x), "Image %s was cached!" % x) for x in xrange(5, 10): self.assertTrue(self.cache.is_cached(x), "Image %s was not cached!" % x) @skip_if_disabled def test_prune_to_zero(self): """Test that an image_cache_max_size of 0 doesn't kill the pruner This is a test specifically for LP #1039854 """ self.assertEqual(0, self.cache.get_cache_size()) FIXTURE_FILE = six.StringIO(FIXTURE_DATA) self.assertTrue(self.cache.cache_image_file('xxx', FIXTURE_FILE)) self.assertEqual(1024, self.cache.get_cache_size()) # OK, hit the image that is now cached... buff = six.StringIO() with self.cache.open_for_read('xxx') as cache_file: for chunk in cache_file: buff.write(chunk) self.config(image_cache_max_size=0) self.cache.prune() self.assertEqual(0, self.cache.get_cache_size()) self.assertFalse(self.cache.is_cached('xxx')) @skip_if_disabled def test_queue(self): """ Test that queueing works properly """ self.assertFalse(self.cache.is_cached(1)) self.assertFalse(self.cache.is_queued(1)) FIXTURE_FILE = six.StringIO(FIXTURE_DATA) self.assertTrue(self.cache.queue_image(1)) self.assertTrue(self.cache.is_queued(1)) self.assertFalse(self.cache.is_cached(1)) # Should not return True if the image is already # queued for caching... self.assertFalse(self.cache.queue_image(1)) self.assertFalse(self.cache.is_cached(1)) # Test that we return False if we try to queue # an image that has already been cached self.assertTrue(self.cache.cache_image_file(1, FIXTURE_FILE)) self.assertFalse(self.cache.is_queued(1)) self.assertTrue(self.cache.is_cached(1)) self.assertFalse(self.cache.queue_image(1)) self.cache.delete_cached_image(1) for x in xrange(3): self.assertTrue(self.cache.queue_image(x)) self.assertEqual(self.cache.get_queued_images(), ['0', '1', '2']) def test_open_for_write_good(self): """ Test to see if open_for_write works in normal case """ # test a good case image_id = '1' self.assertFalse(self.cache.is_cached(image_id)) with self.cache.driver.open_for_write(image_id) as cache_file: cache_file.write('a') self.assertTrue(self.cache.is_cached(image_id), "Image %s was NOT cached!" % image_id) # make sure it has tidied up incomplete_file_path = os.path.join(self.cache_dir, 'incomplete', image_id) invalid_file_path = os.path.join(self.cache_dir, 'invalid', image_id) self.assertFalse(os.path.exists(incomplete_file_path)) self.assertFalse(os.path.exists(invalid_file_path)) def test_open_for_write_with_exception(self): """ Test to see if open_for_write works in a failure case for each driver This case is where an exception is raised while the file is being written. The image is partially filled in cache and filling wont resume so verify the image is moved to invalid/ directory """ # test a case where an exception is raised while the file is open image_id = '1' self.assertFalse(self.cache.is_cached(image_id)) try: with self.cache.driver.open_for_write(image_id): raise IOError except Exception as e: self.assertIsInstance(e, IOError) self.assertFalse(self.cache.is_cached(image_id), "Image %s was cached!" % image_id) # make sure it has tidied up incomplete_file_path = os.path.join(self.cache_dir, 'incomplete', image_id) invalid_file_path = os.path.join(self.cache_dir, 'invalid', image_id) self.assertFalse(os.path.exists(incomplete_file_path)) self.assertTrue(os.path.exists(invalid_file_path)) def test_caching_iterator(self): """ Test to see if the caching iterator interacts properly with the driver When the iterator completes going through the data the driver should have closed the image and placed it correctly """ # test a case where an exception NOT raised while the file is open, # and a consuming iterator completes def consume(image_id): data = ['a', 'b', 'c', 'd', 'e', 'f'] checksum = None caching_iter = self.cache.get_caching_iter(image_id, checksum, iter(data)) self.assertEqual(list(caching_iter), data) image_id = '1' self.assertFalse(self.cache.is_cached(image_id)) consume(image_id) self.assertTrue(self.cache.is_cached(image_id), "Image %s was NOT cached!" % image_id) # make sure it has tidied up incomplete_file_path = os.path.join(self.cache_dir, 'incomplete', image_id) invalid_file_path = os.path.join(self.cache_dir, 'invalid', image_id) self.assertFalse(os.path.exists(incomplete_file_path)) self.assertFalse(os.path.exists(invalid_file_path)) def test_caching_iterator_handles_backend_failure(self): """ Test that when the backend fails, caching_iter does not continue trying to consume data, and rolls back the cache. """ def faulty_backend(): data = ['a', 'b', 'c', 'Fail', 'd', 'e', 'f'] for d in data: if d == 'Fail': raise exception.GlanceException('Backend failure') yield d def consume(image_id): caching_iter = self.cache.get_caching_iter(image_id, None, faulty_backend()) # exercise the caching_iter list(caching_iter) image_id = '1' self.assertRaises(exception.GlanceException, consume, image_id) # make sure bad image was not cached self.assertFalse(self.cache.is_cached(image_id)) def test_caching_iterator_falloffend(self): """ Test to see if the caching iterator interacts properly with the driver in a case where the iterator is only partially consumed. In this case the image is only partially filled in cache and filling wont resume. When the iterator goes out of scope the driver should have closed the image and moved it from incomplete/ to invalid/ """ # test a case where a consuming iterator just stops. def falloffend(image_id): data = ['a', 'b', 'c', 'd', 'e', 'f'] checksum = None caching_iter = self.cache.get_caching_iter(image_id, checksum, iter(data)) self.assertEqual(caching_iter.next(), 'a') image_id = '1' self.assertFalse(self.cache.is_cached(image_id)) falloffend(image_id) self.assertFalse(self.cache.is_cached(image_id), "Image %s was cached!" % image_id) # make sure it has tidied up incomplete_file_path = os.path.join(self.cache_dir, 'incomplete', image_id) invalid_file_path = os.path.join(self.cache_dir, 'invalid', image_id) self.assertFalse(os.path.exists(incomplete_file_path)) self.assertTrue(os.path.exists(invalid_file_path)) def test_gate_caching_iter_good_checksum(self): image = "12345678990abcdefghijklmnop" image_id = 123 md5 = hashlib.md5() md5.update(image) checksum = md5.hexdigest() cache = image_cache.ImageCache() img_iter = cache.get_caching_iter(image_id, checksum, image) for chunk in img_iter: pass # checksum is valid, fake image should be cached: self.assertTrue(cache.is_cached(image_id)) def test_gate_caching_iter_fs_chunked_file(self): """Tests get_caching_iter when using a filesystem ChunkedFile""" image_id = 123 with tempfile.NamedTemporaryFile() as test_data_file: test_data_file.write(FIXTURE_DATA) test_data_file.seek(0) image = fs_store.ChunkedFile(test_data_file.name) md5 = hashlib.md5() md5.update(FIXTURE_DATA) checksum = md5.hexdigest() cache = image_cache.ImageCache() img_iter = cache.get_caching_iter(image_id, checksum, image) for chunk in img_iter: pass # checksum is valid, fake image should be cached: self.assertTrue(cache.is_cached(image_id)) def test_gate_caching_iter_s3_chunked_file(self): """Tests get_caching_iter when using an S3 ChunkedFile""" image_id = 123 with tempfile.NamedTemporaryFile() as test_data_file: test_data_file.write(FIXTURE_DATA) test_data_file.seek(0) image = s3_store.ChunkedFile(test_data_file) md5 = hashlib.md5() md5.update(FIXTURE_DATA) checksum = md5.hexdigest() cache = image_cache.ImageCache() img_iter = cache.get_caching_iter(image_id, checksum, image) for chunk in img_iter: pass # checksum is valid, fake image should be cached: self.assertTrue(cache.is_cached(image_id)) def test_gate_caching_iter_bad_checksum(self): image = "12345678990abcdefghijklmnop" image_id = 123 checksum = "foobar" # bad. cache = image_cache.ImageCache() img_iter = cache.get_caching_iter(image_id, checksum, image) def reader(): for chunk in img_iter: pass self.assertRaises(exception.GlanceException, reader) # checksum is invalid, caching will fail: self.assertFalse(cache.is_cached(image_id)) class TestImageCacheXattr(test_utils.BaseTestCase, ImageCacheTestCase): """Tests image caching when xattr is used in cache""" def setUp(self): """ Test to see if the pre-requisites for the image cache are working (python-xattr installed and xattr support on the filesystem) """ super(TestImageCacheXattr, self).setUp() if getattr(self, 'disable', False): return self.cache_dir = self.useFixture(fixtures.TempDir()).path if not getattr(self, 'inited', False): try: import xattr # noqa except ImportError: self.inited = True self.disabled = True self.disabled_message = ("python-xattr not installed.") return self.inited = True self.disabled = False self.config(image_cache_dir=self.cache_dir, image_cache_driver='xattr', image_cache_max_size=5 * units.Ki) self.cache = image_cache.ImageCache() if not xattr_writes_supported(self.cache_dir): self.inited = True self.disabled = True self.disabled_message = ("filesystem does not support xattr") return class TestImageCacheSqlite(test_utils.BaseTestCase, ImageCacheTestCase): """Tests image caching when SQLite is used in cache""" def setUp(self): """ Test to see if the pre-requisites for the image cache are working (python-sqlite3 installed) """ super(TestImageCacheSqlite, self).setUp() if getattr(self, 'disable', False): return if not getattr(self, 'inited', False): try: import sqlite3 # noqa except ImportError: self.inited = True self.disabled = True self.disabled_message = ("python-sqlite3 not installed.") return self.inited = True self.disabled = False self.cache_dir = self.useFixture(fixtures.TempDir()).path self.config(image_cache_dir=self.cache_dir, image_cache_driver='sqlite', image_cache_max_size=5 * units.Ki) self.cache = image_cache.ImageCache() class TestImageCacheNoDep(test_utils.BaseTestCase): def setUp(self): super(TestImageCacheNoDep, self).setUp() self.driver = None def init_driver(self2): self2.driver = self.driver self.stubs = stubout.StubOutForTesting() self.stubs.Set(image_cache.ImageCache, 'init_driver', init_driver) self.addCleanup(self.stubs.UnsetAll) def test_get_caching_iter_when_write_fails(self): class FailingFile(object): def write(self, data): if data == "Fail": raise IOError class FailingFileDriver(object): def is_cacheable(self, *args, **kwargs): return True @contextmanager def open_for_write(self, *args, **kwargs): yield FailingFile() self.driver = FailingFileDriver() cache = image_cache.ImageCache() data = ['a', 'b', 'c', 'Fail', 'd', 'e', 'f'] caching_iter = cache.get_caching_iter('dummy_id', None, iter(data)) self.assertEqual(list(caching_iter), data) def test_get_caching_iter_when_open_fails(self): class OpenFailingDriver(object): def is_cacheable(self, *args, **kwargs): return True @contextmanager def open_for_write(self, *args, **kwargs): raise IOError self.driver = OpenFailingDriver() cache = image_cache.ImageCache() data = ['a', 'b', 'c', 'd', 'e', 'f'] caching_iter = cache.get_caching_iter('dummy_id', None, iter(data)) self.assertEqual(list(caching_iter), data) glance-2014.1/glance/tests/utils.py0000664000175400017540000004414412323736226020312 0ustar jenkinsjenkins00000000000000# Copyright 2010-2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """Common utilities used in testing""" import errno import functools import os import shlex import shutil import socket import subprocess import fixtures from oslo.config import cfg import six import stubout import testtools import webob from glance.common import config from glance.common import exception from glance.common import property_utils from glance.common import wsgi from glance import context from glance.db.sqlalchemy import api as db_api from glance.db.sqlalchemy import models as db_models from glance.openstack.common import jsonutils from glance.openstack.common import timeutils CONF = cfg.CONF class BaseTestCase(testtools.TestCase): def setUp(self): super(BaseTestCase, self).setUp() #NOTE(bcwaldon): parse_args has to be called to register certain # command-line options - specifically we need config_dir for # the following policy tests config.parse_args(args=[]) self.addCleanup(CONF.reset) self.stubs = stubout.StubOutForTesting() self.stubs.Set(exception, '_FATAL_EXCEPTION_FORMAT_ERRORS', True) self.test_dir = self.useFixture(fixtures.TempDir()).path def tearDown(self): self.stubs.UnsetAll() self.stubs.SmartUnsetAll() super(BaseTestCase, self).tearDown() def set_property_protections(self, use_policies=False): self.unset_property_protections() conf_file = "property-protections.conf" if use_policies: conf_file = "property-protections-policies.conf" self.config(property_protection_rule_format="policies") self.property_file = self._copy_data_file(conf_file, self.test_dir) self.config(property_protection_file=self.property_file) def unset_property_protections(self): for section in property_utils.CONFIG.sections(): property_utils.CONFIG.remove_section(section) def _copy_data_file(self, file_name, dst_dir): src_file_name = os.path.join('glance/tests/etc', file_name) shutil.copy(src_file_name, dst_dir) dst_file_name = os.path.join(dst_dir, file_name) return dst_file_name def set_property_protection_rules(self, rules): f = open(self.property_file, 'w') for rule_key in rules.keys(): f.write('[%s]\n' % rule_key) for operation in rules[rule_key].keys(): roles_str = ','.join(rules[rule_key][operation]) f.write('%s = %s\n' % (operation, roles_str)) f.close() def config(self, **kw): """ Override some configuration values. The keyword arguments are the names of configuration options to override and their values. If a group argument is supplied, the overrides are applied to the specified configuration option group. All overrides are automatically cleared at the end of the current test by the fixtures cleanup process. """ group = kw.pop('group', None) for k, v in kw.iteritems(): CONF.set_override(k, v, group) class requires(object): """Decorator that initiates additional test setup/teardown.""" def __init__(self, setup=None, teardown=None): self.setup = setup self.teardown = teardown def __call__(self, func): def _runner(*args, **kw): if self.setup: self.setup(args[0]) func(*args, **kw) if self.teardown: self.teardown(args[0]) _runner.__name__ = func.__name__ _runner.__doc__ = func.__doc__ return _runner class depends_on_exe(object): """Decorator to skip test if an executable is unavailable""" def __init__(self, exe): self.exe = exe def __call__(self, func): def _runner(*args, **kw): cmd = 'which %s' % self.exe exitcode, out, err = execute(cmd, raise_error=False) if exitcode != 0: args[0].disabled_message = 'test requires exe: %s' % self.exe args[0].disabled = True func(*args, **kw) _runner.__name__ = func.__name__ _runner.__doc__ = func.__doc__ return _runner def skip_if_disabled(func): """Decorator that skips a test if test case is disabled.""" @functools.wraps(func) def wrapped(*a, **kwargs): func.__test__ = False test_obj = a[0] message = getattr(test_obj, 'disabled_message', 'Test disabled') if getattr(test_obj, 'disabled', False): test_obj.skipTest(message) func(*a, **kwargs) return wrapped def fork_exec(cmd, exec_env=None, logfile=None): """ Execute a command using fork/exec. This is needed for programs system executions that need path searching but cannot have a shell as their parent process, for example: glance-api. When glance-api starts it sets itself as the parent process for its own process group. Thus the pid that a Popen process would have is not the right pid to use for killing the process group. This patch gives the test env direct access to the actual pid. :param cmd: Command to execute as an array of arguments. :param exec_env: A dictionary representing the environment with which to run the command. :param logile: A path to a file which will hold the stdout/err of the child process. """ env = os.environ.copy() if exec_env is not None: for env_name, env_val in exec_env.items(): if callable(env_val): env[env_name] = env_val(env.get(env_name)) else: env[env_name] = env_val pid = os.fork() if pid == 0: if logfile: fds = [1, 2] with open(logfile, 'r+b') as fptr: for desc in fds: # close fds try: os.dup2(fptr.fileno(), desc) except OSError: pass args = shlex.split(cmd) os.execvpe(args[0], args, env) else: return pid def wait_for_fork(pid, raise_error=True, expected_exitcode=0): """ Wait for a process to complete This function will wait for the given pid to complete. If the exit code does not match that of the expected_exitcode an error is raised. """ rc = 0 try: (pid, rc) = os.waitpid(pid, 0) rc = os.WEXITSTATUS(rc) if rc != expected_exitcode: raise RuntimeError('The exit code %d is not %d' % (rc, expected_exitcode)) except Exception: if raise_error: raise return rc def execute(cmd, raise_error=True, no_venv=False, exec_env=None, expect_exit=True, expected_exitcode=0, context=None): """ Executes a command in a subprocess. Returns a tuple of (exitcode, out, err), where out is the string output from stdout and err is the string output from stderr when executing the command. :param cmd: Command string to execute :param raise_error: If returncode is not 0 (success), then raise a RuntimeError? Default: True) :param no_venv: Disable the virtual environment :param exec_env: Optional dictionary of additional environment variables; values may be callables, which will be passed the current value of the named environment variable :param expect_exit: Optional flag true iff timely exit is expected :param expected_exitcode: expected exitcode from the launcher :param context: additional context for error message """ env = os.environ.copy() if exec_env is not None: for env_name, env_val in exec_env.items(): if callable(env_val): env[env_name] = env_val(env.get(env_name)) else: env[env_name] = env_val # If we're asked to omit the virtualenv, and if one is set up, # restore the various environment variables if no_venv and 'VIRTUAL_ENV' in env: # Clip off the first element of PATH env['PATH'] = env['PATH'].split(os.pathsep, 1)[-1] del env['VIRTUAL_ENV'] # Make sure that we use the programs in the # current source directory's bin/ directory. path_ext = [os.path.join(os.getcwd(), 'bin')] # Also jack in the path cmd comes from, if it's absolute executable = cmd.split()[0] if os.path.isabs(executable): path_ext.append(os.path.dirname(executable)) env['PATH'] = ':'.join(path_ext) + ':' + env['PATH'] process = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env) if expect_exit: result = process.communicate() (out, err) = result exitcode = process.returncode else: out = '' err = '' exitcode = 0 if exitcode != expected_exitcode and raise_error: msg = "Command %(cmd)s did not succeed. Returned an exit "\ "code of %(exitcode)d."\ "\n\nSTDOUT: %(out)s"\ "\n\nSTDERR: %(err)s" % {'cmd': cmd, 'exitcode': exitcode, 'out': out, 'err': err} if context: msg += "\n\nCONTEXT: %s" % context raise RuntimeError(msg) return exitcode, out, err def find_executable(cmdname): """ Searches the path for a given cmdname. Returns an absolute filename if an executable with the given name exists in the path, or None if one does not. :param cmdname: The bare name of the executable to search for """ # Keep an eye out for the possibility of an absolute pathname if os.path.isabs(cmdname): return cmdname # Get a list of the directories to search path = ([os.path.join(os.getcwd(), 'bin')] + os.environ['PATH'].split(os.pathsep)) # Search through each in turn for elem in path: full_path = os.path.join(elem, cmdname) if os.access(full_path, os.X_OK): return full_path # No dice... return None def get_unused_port(): """ Returns an unused port on localhost. """ port, s = get_unused_port_and_socket() s.close() return port def get_unused_port_and_socket(): """ Returns an unused port on localhost and the open socket from which it was created. """ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind(('localhost', 0)) addr, port = s.getsockname() return (port, s) def xattr_writes_supported(path): """ Returns True if the we can write a file to the supplied path and subsequently write a xattr to that file. """ try: import xattr except ImportError: return False def set_xattr(path, key, value): xattr.setxattr(path, "user.%s" % key, str(value)) # We do a quick attempt to write a user xattr to a temporary file # to check that the filesystem is even enabled to support xattrs fake_filepath = os.path.join(path, 'testing-checkme') result = True with open(fake_filepath, 'wb') as fake_file: fake_file.write("XXX") fake_file.flush() try: set_xattr(fake_filepath, 'hits', '1') except IOError as e: if e.errno == errno.EOPNOTSUPP: result = False else: # Cleanup after ourselves... if os.path.exists(fake_filepath): os.unlink(fake_filepath) return result def minimal_headers(name, public=True): headers = { 'Content-Type': 'application/octet-stream', 'X-Image-Meta-Name': name, 'X-Image-Meta-disk_format': 'raw', 'X-Image-Meta-container_format': 'ovf', } if public: headers['X-Image-Meta-Is-Public'] = 'True' return headers def minimal_add_command(port, name, suffix='', public=True): visibility = 'is_public=True' if public else '' return ("bin/glance --port=%d add %s" " disk_format=raw container_format=ovf" " name=%s %s" % (port, visibility, name, suffix)) class RegistryAPIMixIn(object): def create_fixtures(self): for fixture in self.FIXTURES: db_api.image_create(self.context, fixture) with open(os.path.join(self.test_dir, fixture['id']), 'wb') as image: image.write("chunk00000remainder") def destroy_fixtures(self): db_models.unregister_models(db_api.get_engine()) db_models.register_models(db_api.get_engine()) def get_fixture(self, **kwargs): fixture = {'name': 'fake public image', 'status': 'active', 'disk_format': 'vhd', 'container_format': 'ovf', 'is_public': True, 'size': 20, 'checksum': None} fixture.update(kwargs) return fixture def get_minimal_fixture(self, **kwargs): fixture = {'name': 'fake public image', 'is_public': True, 'disk_format': 'vhd', 'container_format': 'ovf'} fixture.update(kwargs) return fixture def get_extra_fixture(self, id, name, **kwargs): created_at = kwargs.pop('created_at', timeutils.utcnow()) updated_at = kwargs.pop('updated_at', created_at) return self.get_fixture( id=id, name=name, deleted=False, deleted_at=None, created_at=created_at, updated_at=updated_at, **kwargs) def get_api_response_ext(self, http_resp, url='/images', headers={}, body=None, method=None, api=None, content_type=None): if api is None: api = self.api req = webob.Request.blank(url) for k, v in headers.iteritems(): req.headers[k] = v if method: req.method = method if body: req.body = body if content_type == 'json': req.content_type = 'application/json' elif content_type == 'octet': req.content_type = 'application/octet-stream' res = req.get_response(api) self.assertEqual(res.status_int, http_resp) return res def assertEqualImages(self, res, uuids, key='images', unjsonify=True): images = jsonutils.loads(res.body)[key] if unjsonify else res self.assertEqual(len(images), len(uuids)) for i, value in enumerate(uuids): self.assertEqual(images[i]['id'], value) class FakeAuthMiddleware(wsgi.Middleware): def __init__(self, app, is_admin=False): super(FakeAuthMiddleware, self).__init__(app) self.is_admin = is_admin def process_request(self, req): auth_tok = req.headers.get('X-Auth-Token') user = None tenant = None roles = [] if auth_tok: user, tenant, role = auth_tok.split(':') if tenant.lower() == 'none': tenant = None roles = [role] req.headers['X-User-Id'] = user req.headers['X-Tenant-Id'] = tenant req.headers['X-Roles'] = role req.headers['X-Identity-Status'] = 'Confirmed' kwargs = { 'user': user, 'tenant': tenant, 'roles': roles, 'is_admin': self.is_admin, 'auth_tok': auth_tok, } req.context = context.RequestContext(**kwargs) class FakeHTTPResponse(object): def __init__(self, status=200, headers=None, data=None, *args, **kwargs): data = data or 'I am a teapot, short and stout\n' self.data = six.StringIO(data) self.read = self.data.read self.status = status self.headers = headers or {'content-length': len(data)} def getheader(self, name, default=None): return self.headers.get(name.lower(), default) def getheaders(self): return self.headers or {} def read(self, amt): self.data.read(amt) class Httplib2WsgiAdapter(object): def __init__(self, app): self.app = app def request(self, uri, method="GET", body=None, headers=None): req = webob.Request.blank(uri, method=method, headers=headers) req.body = body resp = req.get_response(self.app) return Httplib2WebobResponse(resp), resp.body class Httplib2WebobResponse(object): def __init__(self, webob_resp): self.webob_resp = webob_resp @property def status(self): return self.webob_resp.status_code def __getitem__(self, key): return self.webob_resp.headers[key] def get(self, key): return self.webob_resp.headers[key] @property def allow(self): return self.webob_resp.allow @allow.setter def allow(self, allowed): if type(allowed) is not str: raise TypeError('Allow header should be a str') self.webob_resp.allow = allowed class HttplibWsgiAdapter(object): def __init__(self, app): self.app = app self.req = None def request(self, method, url, body=None, headers={}): self.req = webob.Request.blank(url, method=method, headers=headers) self.req.body = body def getresponse(self): response = self.req.get_response(self.app) return FakeHTTPResponse(response.status_code, response.headers, response.body) glance-2014.1/glance/tests/etc/0000775000175400017540000000000012323736427017347 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/tests/etc/property-protections-policies.conf0000664000175400017540000000163312323736226026256 0ustar jenkinsjenkins00000000000000[spl_creator_policy] create = glance_creator read = glance_creator update = context_is_admin delete = context_is_admin [spl_default_policy] create = context_is_admin read = default update = context_is_admin delete = context_is_admin [^x_all_permitted.*] create = @ read = @ update = @ delete = @ [^x_none_permitted.*] create = ! read = ! update = ! delete = ! [x_none_read] create = context_is_admin read = ! update = ! delete = ! [x_none_update] create = context_is_admin read = context_is_admin update = ! delete = context_is_admin [x_none_delete] create = context_is_admin read = context_is_admin update = context_is_admin delete = ! [x_foo_matcher] create = context_is_admin read = context_is_admin update = context_is_admin delete = context_is_admin [x_foo_*] create = @ read = @ update = @ delete = @ [.*] create = context_is_admin read = context_is_admin update = context_is_admin delete = context_is_admin glance-2014.1/glance/tests/etc/policy.json0000664000175400017540000000121612323736226021536 0ustar jenkinsjenkins00000000000000{ "context_is_admin": "role:admin", "default": "", "glance_creator": "role:admin or role:spl_role", "add_image": "", "delete_image": "", "get_image": "", "get_images": "", "modify_image": "", "publicize_image": "", "copy_from": "", "download_image": "", "upload_image": "", "delete_image_location": "", "get_image_location": "", "set_image_location": "", "add_member": "", "delete_member": "", "get_member": "", "get_members": "", "modify_member": "", "manage_image_cache": "", "get_task": "", "get_tasks": "", "add_task": "", "modify_task": "" } glance-2014.1/glance/tests/etc/schema-image.json0000664000175400017540000000000312323736226022550 0ustar jenkinsjenkins00000000000000{} glance-2014.1/glance/tests/etc/property-protections.conf0000664000175400017540000000234112323736226024446 0ustar jenkinsjenkins00000000000000[^x_owner_.*] create = admin,member read = admin,member update = admin,member delete = admin,member [spl_create_prop] create = admin,spl_role read = admin,spl_role update = admin delete = admin [spl_read_prop] create = admin,spl_role read = admin,spl_role update = admin delete = admin [spl_read_only_prop] create = admin read = admin,spl_role update = admin delete = admin [spl_update_prop] create = admin,spl_role read = admin,spl_role update = admin,spl_role delete = admin [spl_update_only_prop] create = admin read = admin update = admin,spl_role delete = admin [spl_delete_prop] create = admin,spl_role read = admin,spl_role update = admin delete = admin,spl_role [^x_all_permitted.*] create = @ read = @ update = @ delete = @ [^x_none_permitted.*] create = ! read = ! update = ! delete = ! [x_none_read] create = admin,member read = ! update = ! delete = ! [x_none_update] create = admin,member read = admin,member update = ! delete = admin,member [x_none_delete] create = admin,member read = admin,member update = admin,member delete = ! [x_foo_matcher] create = admin read = admin update = admin delete = admin [x_foo_*] create = @ read = @ update = @ delete = @ [.*] create = admin read = admin update = admin delete = admin glance-2014.1/glance/tests/stubs.py0000664000175400017540000001574512323736226020317 0ustar jenkinsjenkins00000000000000# Copyright 2010-2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """Stubouts, mocks and fixtures for the test suite""" import os try: import sendfile SENDFILE_SUPPORTED = True except ImportError: SENDFILE_SUPPORTED = False import routes import webob from glance.api.middleware import context from glance.api.v1 import router import glance.common.client from glance.registry.api import v1 as rserver from glance.tests import utils VERBOSE = False DEBUG = False class FakeRegistryConnection(object): def __init__(self, registry=None): self.registry = registry or rserver def __call__(self, *args, **kwargs): # NOTE(flaper87): This method takes # __init__'s place in the chain. return self def connect(self): return True def close(self): return True def request(self, method, url, body=None, headers=None): self.req = webob.Request.blank("/" + url.lstrip("/")) self.req.method = method if headers: self.req.headers = headers if body: self.req.body = body def getresponse(self): mapper = routes.Mapper() server = self.registry.API(mapper) # NOTE(markwash): we need to pass through context auth information if # we have it. if 'X-Auth-Token' in self.req.headers: api = utils.FakeAuthMiddleware(server) else: api = context.UnauthenticatedContextMiddleware(server) webob_res = self.req.get_response(api) return utils.FakeHTTPResponse(status=webob_res.status_int, headers=webob_res.headers, data=webob_res.body) def stub_out_registry_and_store_server(stubs, base_dir, **kwargs): """ Mocks calls to 127.0.0.1 on 9191 and 9292 for testing so that a real Glance server does not need to be up and running """ class FakeSocket(object): def __init__(self, *args, **kwargs): pass def fileno(self): return 42 class FakeSendFile(object): def __init__(self, req): self.req = req def sendfile(self, o, i, offset, nbytes): os.lseek(i, offset, os.SEEK_SET) prev_len = len(self.req.body) self.req.body += os.read(i, nbytes) return len(self.req.body) - prev_len class FakeGlanceConnection(object): def __init__(self, *args, **kwargs): self.sock = FakeSocket() self.stub_force_sendfile = kwargs.get('stub_force_sendfile', SENDFILE_SUPPORTED) def connect(self): return True def close(self): return True def _clean_url(self, url): #TODO(bcwaldon): Fix the hack that strips off v1 return url.replace('/v1', '', 1) if url.startswith('/v1') else url def putrequest(self, method, url): self.req = webob.Request.blank(self._clean_url(url)) if self.stub_force_sendfile: fake_sendfile = FakeSendFile(self.req) stubs.Set(sendfile, 'sendfile', fake_sendfile.sendfile) self.req.method = method def putheader(self, key, value): self.req.headers[key] = value def endheaders(self): hl = [i.lower() for i in self.req.headers.keys()] assert not ('content-length' in hl and 'transfer-encoding' in hl), \ 'Content-Length and Transfer-Encoding are mutually exclusive' def send(self, data): # send() is called during chunked-transfer encoding, and # data is of the form %x\r\n%s\r\n. Strip off the %x and # only write the actual data in tests. self.req.body += data.split("\r\n")[1] def request(self, method, url, body=None, headers=None): self.req = webob.Request.blank(self._clean_url(url)) self.req.method = method if headers: self.req.headers = headers if body: self.req.body = body def getresponse(self): mapper = routes.Mapper() api = context.UnauthenticatedContextMiddleware(router.API(mapper)) res = self.req.get_response(api) # httplib.Response has a read() method...fake it out def fake_reader(): return res.body setattr(res, 'read', fake_reader) return res def fake_get_connection_type(client): """ Returns the proper connection type """ DEFAULT_REGISTRY_PORT = 9191 DEFAULT_API_PORT = 9292 if (client.port == DEFAULT_API_PORT and client.host == '0.0.0.0'): return FakeGlanceConnection elif (client.port == DEFAULT_REGISTRY_PORT and client.host == '0.0.0.0'): rserver = kwargs.get("registry", None) return FakeRegistryConnection(registry=rserver) def fake_image_iter(self): for i in self.source.app_iter: yield i def fake_sendable(self, body): force = getattr(self, 'stub_force_sendfile', None) if force is None: return self._stub_orig_sendable(body) else: if force: assert glance.common.client.SENDFILE_SUPPORTED return force stubs.Set(glance.common.client.BaseClient, 'get_connection_type', fake_get_connection_type) setattr(glance.common.client.BaseClient, '_stub_orig_sendable', glance.common.client.BaseClient._sendable) stubs.Set(glance.common.client.BaseClient, '_sendable', fake_sendable) def stub_out_registry_server(stubs, **kwargs): """ Mocks calls to 127.0.0.1 on 9191 for testing so that a real Glance Registry server does not need to be up and running """ def fake_get_connection_type(client): """ Returns the proper connection type """ DEFAULT_REGISTRY_PORT = 9191 if (client.port == DEFAULT_REGISTRY_PORT and client.host == '0.0.0.0'): rserver = kwargs.pop("registry", None) return FakeRegistryConnection(registry=rserver) def fake_image_iter(self): for i in self.response.app_iter: yield i stubs.Set(glance.common.client.BaseClient, 'get_connection_type', fake_get_connection_type) glance-2014.1/glance/tests/var/0000775000175400017540000000000012323736427017364 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/tests/var/privatekey.key0000664000175400017540000000625312323736226022264 0ustar jenkinsjenkins00000000000000-----BEGIN RSA PRIVATE KEY----- MIIJKAIBAAKCAgEA16VJEDeqbmr6PoM96NSuJK1XT5dZuzYzSQ8g//mR9BBjXBDe 4moNajxOybI6hjzWbECtXTKF20s/jkovarzXiZwXH8FMeakwLcMgG/QMRpMLjGny FPpVm7HJaPnTxrI2tNcsG10wmWxd9oqp6TjGIX8VlHaEGIgZIccYVvXjDyi0vypD /P28flWmtlyYgHm6pHfZ65LAAAXhnPZpWn2ARJogoT3SRD8PtXjwOEFavWj3qQ7K gCrRjfCS6ZqAtwXcUEE228C90PH01yuLQjVGlZOAGw8vzHBaustKHEKATyY4oTmN +Zlhvzi7XCPfcjzqVhp6bP+Whv+uAwydg+uxZ2o+oCh1fuk1xTvCmcZZ8bYLYmQy QWZJ3kwbfQK0jr/pejQbLpkc9IhCeKOB9Utk0jJ6awL1+1pxrXOl4vYF2oWHAxxH pcMGM6gIkwb+ocUqeDGdnTV2viszorQu2W1dqrINGrtMI3xP6EkNzb7L1K/Jzpn7 rSU7x0QMGwtb+Bv7bgLDuztMNtLtgd7vqRtOpufq5xKqfqwfYZrpEWE34BBUUbFS L6RZf3MLz1ykXF9N1CDMfpS6/Rbfnqe2KKAYWN8GNpMAsQ+JUWDZm8LAiFcsGbeN H/+GnffE5Ln0fTYbH8nMRnqm65kzBZWfE05Zj/NoqIXpCgjr6MhLkyFi9vsCAwEA AQKCAgAA96baQcWr9SLmQOR4NOwLEhQAMWefpWCZhU3amB4FgEVR1mmJjnw868RW t0v36jH0Dl44us9K6o2Ab+jCi9JTtbWM2Osk6JNkwSlVtsSPVH2KxbbmTTExH50N sYE3tPj12rlB7isXpRrOzlRwzWZmJBHOtrFlAsdKFYCQc03vdXlKGkBv1BuSXYP/ 8W5ltSYXMspxehkOZvhaIejbFREMPbzDvGlDER1a7Q320qQ7kUr7ISvbY1XJUzj1 f1HwgEA6w/AhED5Jv6wfgvx+8Yo9hYnflTPbsO1XRS4x7kJxGHTMlFuEsSF1ICYH Bcos0wUiGcBO2N6uAFuhe98BBn+nOwAPZYWwGkmVuK2psm2mXAHx94GT/XqgK/1r VWGSoOV7Fhjauc2Nv8/vJU18DXT3OY5hc4iXVeEBkuZwRb/NVUtnFoHxVO/Mp5Fh /W5KZaLWVrLghzvSQ/KUIM0k4lfKDZpY9ZpOdNgWDyZY8tNrXumUZZimzWdXZ9vR dBssmd8qEKs1AHGFnMDt56IjLGou6j0qnWsLdR1e/WEFsYzGXLVHCv6vXRNkbjqh WFw5nA+2Dw1YAsy+YkTfgx2pOe+exM/wxsVPa7tG9oZ374dywUi1k6VoHw5dkmJw 1hbXqSLZtx2N51G+SpGmNAV4vLUF0y3dy2wnrzFkFT4uxh1w8QKCAQEA+h6LwHTK hgcJx6CQQ6zYRqXo4wdvMooY1FcqJOq7LvJUA2CX5OOLs8qN1TyFrOCuAUTurOrM ABlQ0FpsIaP8TOGz72dHe2eLB+dD6Bqjn10sEFMn54zWd/w9ympQrO9jb5X3ViTh sCcdYyXVS9Hz8nzbbIF+DaKlxF2Hh71uRDxXpMPxRcGbOIuKZXUj6RkTIulzqT6o uawlegWxch05QSgzq/1ASxtjTzo4iuDCAii3N45xqxnB+fV9NXEt4R2oOGquBRPJ LxKcOnaQKBD0YNX4muTq+zPlv/kOb8/ys2WGWDUrNkpyJXqhTve4KONjqM7+iL/U 4WdJuiCjonzk/QKCAQEA3Lc+kNq35FNLxMcnCVcUgkmiCWZ4dyGZZPdqjOPww1+n bbudGPzY1nxOvE60dZM4or/tm6qlXYfb2UU3+OOJrK9s297EQybZ8DTZu2GHyitc NSFV3Gl4cgvKdbieGKkk9X2dV9xSNesNvX9lJEnQxuwHDTeo8ubLHtV88Ml1xokn 7W+IFiyEuUIL4e5/fadbrI3EwMrbCF4+9VcfABx4PTNMzdc8LsncCMXE+jFX8AWp TsT2JezTe5o2WpvBoKMAYhJQNQiaWATn00pDVY/70H1vK3ljomAa1IUdOr/AhAF7 3jL0MYMgXSHzXZOKAtc7yf+QfFWF1Ls8+sen1clJVwKCAQEAp59rB0r+Iz56RmgL 5t7ifs5XujbURemY5E2aN+18DuVmenD0uvfoO1DnJt4NtCNLWhxpXEdq+jH9H/VJ fG4a+ydT4IC1vjVRTrWlo9qeh4H4suQX3S1c2kKY4pvHf25blH/Lp9bFzbkZD8Ze IRcOxxb4MsrBwL+dGnGYD9dbG63ZCtoqSxaKQSX7VS1hKKmeUopj8ivFBdIht5oz JogBQ/J+Vqg9u1gagRFCrYgdXTcOOtRix0lW336vL+6u0ax/fXe5MjvlW3+8Zc3p pIBgVrlvh9ccx8crFTIDg9m4DJRgqaLQV+0ifI2np3WK3RQvSQWYPetZ7sm69ltD bvUGvQKCAQAz5CEhjUqOs8asjOXwnDiGKSmfbCgGWi/mPQUf+rcwN9z1P5a/uTKB utgIDbj/q401Nkp2vrgCNV7KxitSqKxFnTjKuKUL5KZ4gvRtyZBTR751/1BgcauP pJYE91K0GZBG5zGG5pWtd4XTd5Af5/rdycAeq2ddNEWtCiRFuBeohbaNbBtimzTZ GV4R0DDJKf+zoeEQMqEsZnwG0mTHceoS+WylOGU92teQeG7HI7K5C5uymTwFzpgq ByegRd5QFgKRDB0vWsZuyzh1xI/wHdnmOpdYcUGre0zTijhFB7ALWQ32P6SJv3ps av78kSNxZ4j3BM7DbJf6W8sKasZazOghAoIBAHekpBcLq9gRv2+NfLYxWN2sTZVB 1ldwioG7rWvk5YQR2akukecI3NRjtC5gG2vverawG852Y4+oLfgRMHxgp0qNStwX juTykzPkCwZn8AyR+avC3mkrtJyM3IigcYOu4/UoaRDFa0xvCC1EfumpnKXIpHag miSQZf2sVbgqb3/LWvHIg/ceOP9oGJve87/HVfQtBoLaIe5RXCWkqB7mcI/exvTS 8ShaW6v2Fe5Bzdvawj7sbsVYRWe93Aq2tmIgSX320D2RVepb6mjD4nr0IUaM3Yed TFT7e2ikWXyDLLgVkDTU4Qe8fr3ZKGfanCIDzvgNw6H1gRi+2WQgOmjilMQ= -----END RSA PRIVATE KEY----- glance-2014.1/glance/tests/var/certificate.crt0000664000175400017540000000350212323736226022355 0ustar jenkinsjenkins00000000000000-----BEGIN CERTIFICATE----- MIIFLjCCAxYCAQEwDQYJKoZIhvcNAQEFBQAwYTELMAkGA1UEBhMCQVUxEzARBgNV BAgTClNvbWUtU3RhdGUxFTATBgNVBAoTDE9wZW5zdGFjayBDQTESMBAGA1UECxMJ R2xhbmNlIENBMRIwEAYDVQQDEwlHbGFuY2UgQ0EwHhcNMTIwMjA5MTcxMDUzWhcN MjIwMjA2MTcxMDUzWjBZMQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0 ZTESMBAGA1UEChMJT3BlbnN0YWNrMQ8wDQYDVQQLEwZHbGFuY2UxEDAOBgNVBAMT BzAuMC4wLjAwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXpUkQN6pu avo+gz3o1K4krVdPl1m7NjNJDyD/+ZH0EGNcEN7iag1qPE7JsjqGPNZsQK1dMoXb Sz+OSi9qvNeJnBcfwUx5qTAtwyAb9AxGkwuMafIU+lWbsclo+dPGsja01ywbXTCZ bF32iqnpOMYhfxWUdoQYiBkhxxhW9eMPKLS/KkP8/bx+Vaa2XJiAebqkd9nrksAA BeGc9mlafYBEmiChPdJEPw+1ePA4QVq9aPepDsqAKtGN8JLpmoC3BdxQQTbbwL3Q 8fTXK4tCNUaVk4AbDy/McFq6y0ocQoBPJjihOY35mWG/OLtcI99yPOpWGnps/5aG /64DDJ2D67Fnaj6gKHV+6TXFO8KZxlnxtgtiZDJBZkneTBt9ArSOv+l6NBsumRz0 iEJ4o4H1S2TSMnprAvX7WnGtc6Xi9gXahYcDHEelwwYzqAiTBv6hxSp4MZ2dNXa+ KzOitC7ZbV2qsg0au0wjfE/oSQ3NvsvUr8nOmfutJTvHRAwbC1v4G/tuAsO7O0w2 0u2B3u+pG06m5+rnEqp+rB9hmukRYTfgEFRRsVIvpFl/cwvPXKRcX03UIMx+lLr9 Ft+ep7YooBhY3wY2kwCxD4lRYNmbwsCIVywZt40f/4ad98TkufR9NhsfycxGeqbr mTMFlZ8TTlmP82iohekKCOvoyEuTIWL2+wIDAQABMA0GCSqGSIb3DQEBBQUAA4IC AQBMUBgV0R+Qltf4Du7u/8IFmGAoKR/mktB7R1gRRAqsvecUt7kIwBexGdavGg1y 0pU0+lgUZjJ20N1SlPD8gkNHfXE1fL6fmMjWz4dtYJjzRVhpufHPeBW4tl8DgHPN rBGAYQ+drDSXaEjiPQifuzKx8WS+DGA3ki4co5mPjVnVH1xvLIdFsk89z3b3YD1k yCJ/a9K36x6Z/c67JK7s6MWtrdRF9+MVnRKJ2PK4xznd1kBz16V+RA466wBDdARY vFbtkafbEqOb96QTonIZB7+fAldKDPZYnwPqasreLmaGOaM8sxtlPYAJ5bjDONbc AaXG8BMRQyO4FyH237otDKlxPyHOFV66BaffF5S8OlwIMiZoIvq+IcTZOdtDUSW2 KHNLfe5QEDZdKjWCBrfqAfvNuG13m03WqfmcMHl3o/KiPJlx8l9Z4QEzZ9xcyQGL cncgeHM9wJtzi2cD/rTDNFsx/gxvoyutRmno7I3NRbKmpsXF4StZioU3USRspB07 hYXOVnG3pS+PjVby7ThT3gvFHSocguOsxClx1epdUJAmJUbmM7NmOp5WVBVtMtC2 Su4NG/xJciXitKzw+btb7C7RjO6OEqv/1X/oBDzKBWQAwxUC+lqmnM7W6oqWJFEM YfTLnrjs7Hj6ThMGcEnfvc46dWK3dz0RjsQzUxugPuEkLA== -----END CERTIFICATE----- glance-2014.1/glance/tests/var/ca.crt0000664000175400017540000000415712323736226020465 0ustar jenkinsjenkins00000000000000-----BEGIN CERTIFICATE----- MIIGDDCCA/SgAwIBAgIJAPSvwQYk4qI4MA0GCSqGSIb3DQEBBQUAMGExCzAJBgNV BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMRUwEwYDVQQKEwxPcGVuc3RhY2sg Q0ExEjAQBgNVBAsTCUdsYW5jZSBDQTESMBAGA1UEAxMJR2xhbmNlIENBMB4XDTEy MDIwOTE3MTAwMloXDTIyMDIwNjE3MTAwMlowYTELMAkGA1UEBhMCQVUxEzARBgNV BAgTClNvbWUtU3RhdGUxFTATBgNVBAoTDE9wZW5zdGFjayBDQTESMBAGA1UECxMJ R2xhbmNlIENBMRIwEAYDVQQDEwlHbGFuY2UgQ0EwggIiMA0GCSqGSIb3DQEBAQUA A4ICDwAwggIKAoICAQDmf+fapWfzy1Uylus0KGalw4X/5xZ+ltPVOr+IdCPbstvi RTC5g+O+TvXeOP32V/cnSY4ho/+f2q730za+ZA/cgWO252rcm3Q7KTJn3PoqzJvX /l3EXe3/TCrbzgZ7lW3QLTCTEE2eEzwYG3wfDTOyoBq+F6ct6ADh+86gmpbIRfYI N+ixB0hVyz9427PTof97fL7qxxkjAayB28OfwHrkEBl7iblNhUC0RoH+/H9r5GEl GnWiebxfNrONEHug6PHgiaGq7/Dj+u9bwr7J3/NoS84I08ajMnhlPZxZ8bS/O8If ceWGZv7clPozyhABT/otDfgVcNH1UdZ4zLlQwc1MuPYN7CwxrElxc8Quf94ttGjb tfGTl4RTXkDofYdG1qBWW962PsGl2tWmbYDXV0q5JhV/IwbrE1X9f+OksJQne1/+ dZDxMhdf2Q1V0P9hZZICu4+YhmTMs5Mc9myKVnzp4NYdX5fXoB/uNYph+G7xG5IK WLSODKhr1wFGTTcuaa8LhOH5UREVenGDJuc6DdgX9a9PzyJGIi2ngQ03TJIkCiU/ 4J/r/vsm81ezDiYZSp2j5JbME+ixW0GBLTUWpOIxUSHgUFwH5f7lQwbXWBOgwXQk BwpZTmdQx09MfalhBtWeu4/6BnOCOj7e/4+4J0eVxXST0AmVyv8YjJ2nz1F9oQID AQABo4HGMIHDMB0GA1UdDgQWBBTk7Krj4bEsTjHXaWEtI2GZ5ACQyTCBkwYDVR0j BIGLMIGIgBTk7Krj4bEsTjHXaWEtI2GZ5ACQyaFlpGMwYTELMAkGA1UEBhMCQVUx EzARBgNVBAgTClNvbWUtU3RhdGUxFTATBgNVBAoTDE9wZW5zdGFjayBDQTESMBAG A1UECxMJR2xhbmNlIENBMRIwEAYDVQQDEwlHbGFuY2UgQ0GCCQD0r8EGJOKiODAM BgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4ICAQA8Zrss/MiwFHGmDlercE0h UvzA54n/EvKP9nP3jHM2qW/VPfKdnFw99nEPFLhb+lN553vdjOpCYFm+sW0Z5Mi4 qsFkk4AmXIIEFOPt6zKxMioLYDQ9Sw/BUv6EZGeANWr/bhmaE+dMcKJt5le/0jJm 2ahsVB9fbFu9jBFeYb7Ba/x2aLkEGMxaDLla+6EQhj148fTnS1wjmX9G2cNzJvj/ +C2EfKJIuDJDqw2oS2FGVpP37FA2Bz2vga0QatNneLkGKCFI3ZTenBznoN+fmurX TL3eJE4IFNrANCcdfMpdyLAtXz4KpjcehqpZMu70er3d30zbi1l0Ajz4dU+WKz/a NQES+vMkT2wqjXHVTjrNwodxw3oLK/EuTgwoxIHJuplx5E5Wrdx9g7Gl1PBIJL8V xiOYS5N7CakyALvdhP7cPubA2+TPAjNInxiAcmhdASS/Vrmpvrkat6XhGn8h9liv ysDOpMQmYQkmgZBpW8yBKK7JABGGsJADJ3E6J5MMWBX2RR4kFoqVGAzdOU3oyaTy I0kz5sfuahaWpdYJVlkO+esc0CRXw8fLDYivabK2tOgUEWeZsZGZ9uK6aV1VxTAY 9Guu3BJ4Rv/KP/hk7mP8rIeCwotV66/2H8nq72ImQhzSVyWcxbFf2rJiFQJ3BFwA WoRMgEwjGJWqzhJZUYpUAQ== -----END CERTIFICATE----- glance-2014.1/glance/tests/functional/0000775000175400017540000000000012323736427020736 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/tests/functional/store/0000775000175400017540000000000012323736427022072 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/tests/functional/store/test_cinder.py0000664000175400017540000000635412323736226024754 0ustar jenkinsjenkins00000000000000# Copyright 2013 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ Functional tests for the Cinder store interface """ import os import oslo.config.cfg import testtools import glance.store.cinder as cinder import glance.tests.functional.store as store_tests import glance.tests.functional.store.test_swift as store_tests_swift import glance.tests.utils def parse_config(config): out = {} options = [ 'test_cinder_store_auth_address', 'test_cinder_store_auth_version', 'test_cinder_store_tenant', 'test_cinder_store_user', 'test_cinder_store_key', ] for option in options: out[option] = config.defaults()[option] return out class TestCinderStore(store_tests.BaseTestCase, testtools.TestCase): store_cls_path = 'glance.store.cinder.Store' store_cls = glance.store.cinder.Store store_name = 'cinder' def setUp(self): config_path = os.environ.get('GLANCE_TEST_CINDER_CONF') if not config_path: msg = "GLANCE_TEST_CINDER_CONF environ not set." self.skipTest(msg) oslo.config.cfg.CONF(args=[], default_config_files=[config_path]) raw_config = store_tests_swift.read_config(config_path) try: self.cinder_config = parse_config(raw_config) ret = store_tests_swift.keystone_authenticate( self.cinder_config['test_cinder_store_auth_address'], self.cinder_config['test_cinder_store_auth_version'], self.cinder_config['test_cinder_store_tenant'], self.cinder_config['test_cinder_store_user'], self.cinder_config['test_cinder_store_key']) (tenant_id, auth_token, service_catalog) = ret self.context = glance.context.RequestContext( tenant=tenant_id, service_catalog=service_catalog, auth_tok=auth_token) self.cinder_client = cinder.get_cinderclient(self.context) except Exception as e: msg = "Cinder backend isn't set up: %s" % e self.skipTest(msg) super(TestCinderStore, self).setUp() def get_store(self, **kwargs): store = cinder.Store(context=kwargs.get('context') or self.context) store.configure() store.configure_add() return store def stash_image(self, image_id, image_data): #(zhiyan): Currently cinder store is a partial implementation, # after Cinder expose 'brick' library, 'host-volume-attaching' and # 'multiple-attaching' enhancement ready, the store will support # ADD/GET/DELETE interface. raise NotImplementedError('stash_image can not be implemented so far') glance-2014.1/glance/tests/functional/store/test_s3.py0000664000175400017540000000745312323736226024036 0ustar jenkinsjenkins00000000000000# Copyright 2012 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ Functional tests for the S3 store interface Set the GLANCE_TEST_S3_CONF environment variable to the location of a Glance config that defines how to connect to a functional S3 backend """ import ConfigParser import os import os.path import oslo.config.cfg import six.moves.urllib.parse as urlparse import testtools import glance.store.s3 import glance.tests.functional.store as store_tests try: from boto.s3.connection import S3Connection except ImportError: S3Connection = None def read_config(path): cp = ConfigParser.RawConfigParser() cp.read(path) return cp def parse_config(config): out = {} options = [ 's3_store_host', 's3_store_access_key', 's3_store_secret_key', 's3_store_bucket', 's3_store_bucket_url_format', ] for option in options: out[option] = config.defaults()[option] return out def s3_connect(s3_host, access_key, secret_key, calling_format): return S3Connection(access_key, secret_key, host=s3_host, is_secure=False, calling_format=calling_format) def s3_put_object(s3_client, bucket_name, object_name, contents): bucket = s3_client.get_bucket(bucket_name) key = bucket.new_key(object_name) key.set_contents_from_string(contents) class TestS3Store(store_tests.BaseTestCase, testtools.TestCase): store_cls_path = 'glance.store.s3.Store' store_cls = glance.store.s3.Store store_name = 's3' def setUp(self): config_path = os.environ.get('GLANCE_TEST_S3_CONF') if not config_path: msg = "GLANCE_TEST_S3_CONF environ not set." self.skipTest(msg) oslo.config.cfg.CONF(args=[], default_config_files=[config_path]) raw_config = read_config(config_path) config = parse_config(raw_config) calling_format = glance.store.s3.get_calling_format( config['s3_store_bucket_url_format']) s3_client = s3_connect(config['s3_store_host'], config['s3_store_access_key'], config['s3_store_secret_key'], calling_format) #NOTE(bcwaldon): ensure we have a functional S3 connection s3_client.get_all_buckets() self.s3_client = s3_client self.s3_config = config super(TestS3Store, self).setUp() def get_store(self, **kwargs): store = glance.store.s3.Store(context=kwargs.get('context')) store.configure() store.configure_add() return store def stash_image(self, image_id, image_data): bucket_name = self.s3_config['s3_store_bucket'] s3_put_object(self.s3_client, bucket_name, image_id, 'XXX') s3_store_host = urlparse.urlparse(self.s3_config['s3_store_host']) access_key = urlparse.quote(self.s3_config['s3_store_access_key']) secret_key = self.s3_config['s3_store_secret_key'] auth_chunk = '%s:%s' % (access_key, secret_key) netloc = '%s@%s' % (auth_chunk, s3_store_host.netloc) path = os.path.join(s3_store_host.path, bucket_name, image_id) # This is an s3 url with // on the end return 's3://%s%s' % (netloc, path) glance-2014.1/glance/tests/functional/store/test_sheepdog.py0000664000175400017540000000524312323736226025302 0ustar jenkinsjenkins00000000000000# Copyright 2013 Taobao 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 tests for the Sheepdog store interface """ import os import os.path import fixtures import oslo.config.cfg import testtools from glance.store import BackendException import glance.store.sheepdog as sheepdog import glance.tests.functional.store as store_tests import glance.tests.utils class TestSheepdogStore(store_tests.BaseTestCase, testtools.TestCase): store_cls_path = 'glance.store.sheepdog.Store' store_cls = glance.store.sheepdog.Store store_name = 'sheepdog' def setUp(self): image = sheepdog.SheepdogImage(sheepdog.DEFAULT_ADDR, sheepdog.DEFAULT_PORT, "test", sheepdog.DEFAULT_CHUNKSIZE) try: image.create(512) except BackendException: msg = "Sheepdog cluster isn't set up" self.skipTest(msg) image.delete() self.tmp_dir = self.useFixture(fixtures.TempDir()).path config_file = os.path.join(self.tmp_dir, 'glance.conf') with open(config_file, 'w') as f: f.write("[DEFAULT]\n") f.write("default_store = sheepdog") oslo.config.cfg.CONF(default_config_files=[config_file], args=[]) super(TestSheepdogStore, self).setUp() def get_store(self, **kwargs): store = sheepdog.Store(context=kwargs.get('context')) store.configure() store.configure_add() return store def stash_image(self, image_id, image_data): image_size = len(image_data) image = sheepdog.SheepdogImage(sheepdog.DEFAULT_ADDR, sheepdog.DEFAULT_PORT, image_id, sheepdog.DEFAULT_CHUNKSIZE) image.create(image_size) total = left = image_size while left > 0: length = min(sheepdog.DEFAULT_CHUNKSIZE, left) image.write(image_data, total - left, length) left -= length return 'sheepdog://%s' % image_id glance-2014.1/glance/tests/functional/store/test_swift.py0000664000175400017540000004665712323736226024656 0ustar jenkinsjenkins00000000000000# Copyright 2012 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ Functional tests for the Swift store interface Set the GLANCE_TEST_SWIFT_CONF environment variable to the location of a Glance config that defines how to connect to a functional Swift backend """ import ConfigParser import hashlib import os import os.path import random import string import uuid import oslo.config.cfg import six import six.moves.urllib.parse as urlparse import testtools from glance.common import exception import glance.common.utils as common_utils import glance.store.swift import glance.tests.functional.store as store_tests try: import swiftclient except ImportError: swiftclient = None class SwiftStoreError(RuntimeError): pass def _uniq(value): return '%s.%d' % (value, random.randint(0, 99999)) def read_config(path): cp = ConfigParser.RawConfigParser() cp.read(path) return cp def parse_config(config): out = {} options = [ 'swift_store_auth_address', 'swift_store_auth_version', 'swift_store_user', 'swift_store_key', 'swift_store_container', ] for option in options: out[option] = config.defaults()[option] return out def swift_connect(auth_url, auth_version, user, key): try: return swiftclient.Connection(authurl=auth_url, auth_version=auth_version, user=user, key=key, snet=False, retries=1) except AttributeError: raise SwiftStoreError("Could not find swiftclient module") def swift_list_containers(swift_conn): try: _, containers = swift_conn.get_account() except Exception as e: msg = ("Failed to list containers (get_account) " "from Swift. Got error: %s" % e) raise SwiftStoreError(msg) else: return containers def swift_create_container(swift_conn, container_name): try: swift_conn.put_container(container_name) except swiftclient.ClientException as e: msg = "Failed to create container. Got error: %s" % e raise SwiftStoreError(msg) def swift_get_container(swift_conn, container_name, **kwargs): return swift_conn.get_container(container_name, **kwargs) def swift_delete_container(swift_conn, container_name): try: swift_conn.delete_container(container_name) except swiftclient.ClientException as e: msg = "Failed to delete container from Swift. Got error: %s" % e raise SwiftStoreError(msg) def swift_put_object(swift_conn, container_name, object_name, contents): return swift_conn.put_object(container_name, object_name, contents) def swift_head_object(swift_conn, container_name, obj_name): return swift_conn.head_object(container_name, obj_name) def keystone_authenticate(auth_url, auth_version, tenant_name, username, password): assert int(auth_version) == 2, 'Only auth version 2 is supported' import keystoneclient.v2_0.client ksclient = keystoneclient.v2_0.client.Client(tenant_name=tenant_name, username=username, password=password, auth_url=auth_url) auth_resp = ksclient.service_catalog.catalog tenant_id = auth_resp['token']['tenant']['id'] service_catalog = auth_resp['serviceCatalog'] return tenant_id, ksclient.auth_token, service_catalog class TestSwiftStore(store_tests.BaseTestCase, testtools.TestCase): store_cls_path = 'glance.store.swift.Store' store_cls = glance.store.swift.Store store_name = 'swift' def setUp(self): config_path = os.environ.get('GLANCE_TEST_SWIFT_CONF') if not config_path: msg = "GLANCE_TEST_SWIFT_CONF environ not set." self.skipTest(msg) oslo.config.cfg.CONF(args=[], default_config_files=[config_path]) raw_config = read_config(config_path) config = parse_config(raw_config) swift = swift_connect(config['swift_store_auth_address'], config['swift_store_auth_version'], config['swift_store_user'], config['swift_store_key']) #NOTE(bcwaldon): Ensure we have a functional swift connection swift_list_containers(swift) self.swift_client = swift self.swift_config = config self.swift_config['swift_store_create_container_on_put'] = True super(TestSwiftStore, self).setUp() def get_store(self, **kwargs): store = glance.store.swift.Store(context=kwargs.get('context')) store.configure() store.configure_add() return store def test_object_chunking(self): """Upload an image that is split into multiple swift objects. We specifically check the case that image_size % swift_store_large_object_chunk_size != 0 to ensure we aren't losing image data. """ self.config( swift_store_large_object_size=2, # 2 MB swift_store_large_object_chunk_size=2, # 2 MB ) store = self.get_store() image_id = str(uuid.uuid4()) image_size = 5242880 # 5 MB image_data = six.StringIO('X' * image_size) image_checksum = 'eb7f8c3716b9f059cee7617a4ba9d0d3' uri, add_size, add_checksum, _ = store.add(image_id, image_data, image_size) self.assertEqual(image_size, add_size) self.assertEqual(image_checksum, add_checksum) location = glance.store.location.Location( self.store_name, store.get_store_location_class(), uri=uri, image_id=image_id) # Store interface should still be respected even though # we are storing images in multiple Swift objects (get_iter, get_size) = store.get(location) self.assertEqual(5242880, get_size) self.assertEqual('X' * 5242880, ''.join(get_iter)) # The object should have a manifest pointing to the chunks # of image data swift_location = location.store_location headers = swift_head_object(self.swift_client, swift_location.container, swift_location.obj) manifest = headers.get('x-object-manifest') self.assertTrue(manifest) # Verify the objects in the manifest exist manifest_container, manifest_prefix = manifest.split('/', 1) container = swift_get_container(self.swift_client, manifest_container, prefix=manifest_prefix) segments = [segment['name'] for segment in container[1]] for segment in segments: headers = swift_head_object(self.swift_client, manifest_container, segment) self.assertTrue(headers.get('content-length')) # Since we used a 5 MB image with a 2 MB chunk size, we should # expect to see three data objects self.assertEqual(3, len(segments), 'Got segments %s' % segments) # Add an object that should survive the delete operation non_image_obj = image_id + '0' swift_put_object(self.swift_client, manifest_container, non_image_obj, 'XXX') store.delete(location) # Verify the segments in the manifest are all gone for segment in segments: self.assertRaises(swiftclient.ClientException, swift_head_object, self.swift_client, manifest_container, segment) # Verify the manifest is gone too self.assertRaises(swiftclient.ClientException, swift_head_object, self.swift_client, manifest_container, swift_location.obj) # Verify that the non-image object was not deleted headers = swift_head_object(self.swift_client, manifest_container, non_image_obj) self.assertTrue(headers.get('content-length')) # Clean up self.swift_client.delete_object(manifest_container, non_image_obj) # Simulate exceeding 'image_size_cap' setting image_data = six.StringIO('X' * image_size) image_data = common_utils.LimitingReader(image_data, image_size - 1) image_id = str(uuid.uuid4()) self.assertRaises(exception.ImageSizeLimitExceeded, store.add, image_id, image_data, image_size) # Verify written segments have been deleted container = swift_get_container(self.swift_client, manifest_container, prefix=image_id) segments = [segment['name'] for segment in container[1]] self.assertEqual(0, len(segments), 'Got segments %s' % segments) def test_retries_fail_start_of_download(self): """ Get an object from Swift where Swift does not complete the request in one attempt. Fails at the start of the download. """ self.config( swift_store_retry_get_count=1, ) store = self.get_store() image_id = str(uuid.uuid4()) image_size = 1024 * 1024 * 5 # 5 MB chars = string.ascii_uppercase + string.digits image_data = ''.join(random.choice(chars) for x in range(image_size)) image_checksum = hashlib.md5(image_data) uri, add_size, add_checksum, _ = store.add(image_id, image_data, image_size) location = glance.store.location.Location( self.store_name, store.get_store_location_class(), uri=uri, image_id=image_id) def iter_wrapper(iterable): # raise StopIteration as soon as iteration begins yield '' (get_iter, get_size) = store.get(location) get_iter.wrapped = glance.store.swift.swift_retry_iter( iter_wrapper(get_iter.wrapped), image_size, store, location.store_location) self.assertEqual(image_size, get_size) received_data = ''.join(get_iter.wrapped) self.assertEqual(image_data, received_data) self.assertEqual(image_checksum.hexdigest(), hashlib.md5(received_data).hexdigest()) def test_retries_fail_partway_through_download(self): """ Get an object from Swift where Swift does not complete the request in one attempt. Fails partway through the download. """ self.config( swift_store_retry_get_count=1, ) store = self.get_store() image_id = str(uuid.uuid4()) image_size = 1024 * 1024 * 5 # 5 MB chars = string.ascii_uppercase + string.digits image_data = ''.join(random.choice(chars) for x in range(image_size)) image_checksum = hashlib.md5(image_data) uri, add_size, add_checksum, _ = store.add(image_id, image_data, image_size) location = glance.store.location.Location( self.store_name, store.get_store_location_class(), uri=uri, image_id=image_id) def iter_wrapper(iterable): bytes_received = 0 for chunk in iterable: yield chunk bytes_received += len(chunk) if bytes_received > (image_size / 2): raise StopIteration (get_iter, get_size) = store.get(location) get_iter.wrapped = glance.store.swift.swift_retry_iter( iter_wrapper(get_iter.wrapped), image_size, store, location.store_location) self.assertEqual(image_size, get_size) received_data = ''.join(get_iter.wrapped) self.assertEqual(image_data, received_data) self.assertEqual(image_checksum.hexdigest(), hashlib.md5(received_data).hexdigest()) def test_retries_fail_end_of_download(self): """ Get an object from Swift where Swift does not complete the request in one attempt. Fails at the end of the download """ self.config( swift_store_retry_get_count=1, ) store = self.get_store() image_id = str(uuid.uuid4()) image_size = 1024 * 1024 * 5 # 5 MB chars = string.ascii_uppercase + string.digits image_data = ''.join(random.choice(chars) for x in range(image_size)) image_checksum = hashlib.md5(image_data) uri, add_size, add_checksum, _ = store.add(image_id, image_data, image_size) location = glance.store.location.Location( self.store_name, store.get_store_location_class(), uri=uri, image_id=image_id) def iter_wrapper(iterable): bytes_received = 0 for chunk in iterable: yield chunk bytes_received += len(chunk) if bytes_received == image_size: raise StopIteration (get_iter, get_size) = store.get(location) get_iter.wrapped = glance.store.swift.swift_retry_iter( iter_wrapper(get_iter.wrapped), image_size, store, location.store_location) self.assertEqual(image_size, get_size) received_data = ''.join(get_iter.wrapped) self.assertEqual(image_data, received_data) self.assertEqual(image_checksum.hexdigest(), hashlib.md5(received_data).hexdigest()) def stash_image(self, image_id, image_data): container_name = self.swift_config['swift_store_container'] swift_put_object(self.swift_client, container_name, image_id, 'XXX') #NOTE(bcwaldon): This is a hack until we find a better way to # build this URL auth_url = self.swift_config['swift_store_auth_address'] auth_url = urlparse.urlparse(auth_url) user = urlparse.quote(self.swift_config['swift_store_user']) key = self.swift_config['swift_store_key'] netloc = ''.join(('%s:%s' % (user, key), '@', auth_url.netloc)) path = os.path.join(auth_url.path, container_name, image_id) # This is an auth url with // on the end return 'swift+http://%s%s' % (netloc, path) def test_multitenant(self): """Ensure an image is properly configured when using multitenancy.""" self.config( swift_store_multi_tenant=True, ) swift_store_user = self.swift_config['swift_store_user'] tenant_name, username = swift_store_user.split(':') tenant_id, auth_token, service_catalog = keystone_authenticate( self.swift_config['swift_store_auth_address'], self.swift_config['swift_store_auth_version'], tenant_name, username, self.swift_config['swift_store_key']) context = glance.context.RequestContext( tenant=tenant_id, service_catalog=service_catalog, auth_tok=auth_token) store = self.get_store(context=context) image_id = str(uuid.uuid4()) image_data = six.StringIO('XXX') uri, _, _, _ = store.add(image_id, image_data, 3) location = glance.store.location.Location( self.store_name, store.get_store_location_class(), uri=uri, image_id=image_id) read_tenant = str(uuid.uuid4()) write_tenant = str(uuid.uuid4()) store.set_acls(location, public=False, read_tenants=[read_tenant], write_tenants=[write_tenant]) container_name = location.store_location.container container, _ = swift_get_container(self.swift_client, container_name) self.assertEqual(read_tenant + ':*', container.get('x-container-read')) self.assertEqual(write_tenant + ':*', container.get('x-container-write')) store.set_acls(location, public=True, read_tenants=[read_tenant]) container_name = location.store_location.container container, _ = swift_get_container(self.swift_client, container_name) self.assertEqual('.r:*,.rlistings', container.get('x-container-read')) self.assertEqual('', container.get('x-container-write', '')) (get_iter, get_size) = store.get(location) self.assertEqual(3, get_size) self.assertEqual('XXX', ''.join(get_iter)) store.delete(location) def test_delayed_delete_with_auth(self): """Ensure delete works with delayed delete and auth Reproduces LP bug 1238604. """ swift_store_user = self.swift_config['swift_store_user'] tenant_name, username = swift_store_user.split(':') tenant_id, auth_token, service_catalog = keystone_authenticate( self.swift_config['swift_store_auth_address'], self.swift_config['swift_store_auth_version'], tenant_name, username, self.swift_config['swift_store_key']) context = glance.context.RequestContext( tenant=tenant_id, service_catalog=service_catalog, auth_tok=auth_token) store = self.get_store(context=context) image_id = str(uuid.uuid4()) image_data = six.StringIO('data') uri, _, _, _ = store.add(image_id, image_data, 4) location = glance.store.location.Location( self.store_name, store.get_store_location_class(), uri=uri, image_id=image_id) container_name = location.store_location.container container, _ = swift_get_container(self.swift_client, container_name) (get_iter, get_size) = store.get(location) self.assertEqual(4, get_size) self.assertEqual('data', ''.join(get_iter)) glance.store.schedule_delayed_delete_from_backend(context, uri, image_id) store.delete(location) glance-2014.1/glance/tests/functional/store/test_filesystem.py0000664000175400017540000000371212323736226025667 0ustar jenkinsjenkins00000000000000# Copyright 2012 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ Functional tests for the File store interface """ import os import os.path import fixtures import oslo.config.cfg import testtools import glance.store.filesystem import glance.tests.functional.store as store_tests class TestFilesystemStore(store_tests.BaseTestCase, testtools.TestCase): store_cls_path = 'glance.store.filesystem.Store' store_cls = glance.store.filesystem.Store store_name = 'filesystem' def setUp(self): super(TestFilesystemStore, self).setUp() self.tmp_dir = self.useFixture(fixtures.TempDir()).path self.store_dir = os.path.join(self.tmp_dir, 'images') os.mkdir(self.store_dir) config_file = os.path.join(self.tmp_dir, 'glance.conf') with open(config_file, 'w') as fap: fap.write("[DEFAULT]\n") fap.write("filesystem_store_datadir=%s" % self.store_dir) oslo.config.cfg.CONF(default_config_files=[config_file], args=[]) def get_store(self, **kwargs): store = glance.store.filesystem.Store(context=kwargs.get('context')) store.configure() store.configure_add() return store def stash_image(self, image_id, image_data): filepath = os.path.join(self.store_dir, image_id) with open(filepath, 'w') as fap: fap.write(image_data) return 'file://%s' % filepath glance-2014.1/glance/tests/functional/store/test_http.py0000664000175400017540000000513012323736226024456 0ustar jenkinsjenkins00000000000000# Copyright 2012 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ Functional tests for the File store interface """ import BaseHTTPServer import os import signal import testtools import glance.store.http import glance.tests.functional.store as store_tests def get_handler_class(fixture): class StaticHTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): def do_GET(self): self.send_response(200) self.send_header('Content-Length', str(len(fixture))) self.end_headers() self.wfile.write(fixture) return def do_HEAD(self): self.send_response(200) self.send_header('Content-Length', str(len(fixture))) self.end_headers() return def log_message(*args, **kwargs): # Override this method to prevent debug output from going # to stderr during testing return return StaticHTTPRequestHandler def http_server(image_id, image_data): server_address = ('127.0.0.1', 0) handler_class = get_handler_class(image_data) httpd = BaseHTTPServer.HTTPServer(server_address, handler_class) port = httpd.socket.getsockname()[1] pid = os.fork() if pid == 0: httpd.serve_forever() else: return pid, port class TestHTTPStore(store_tests.BaseTestCase, testtools.TestCase): store_cls_path = 'glance.store.http.Store' store_cls = glance.store.http.Store store_name = 'http' def setUp(self): super(TestHTTPStore, self).setUp() self.kill_pid = None def tearDown(self): if self.kill_pid is not None: os.kill(self.kill_pid, signal.SIGKILL) super(TestHTTPStore, self).tearDown() def get_store(self, **kwargs): store = glance.store.http.Store(context=kwargs.get('context')) store.configure() return store def stash_image(self, image_id, image_data): self.kill_pid, http_port = http_server(image_id, image_data) return 'http://127.0.0.1:%s/' % (http_port,) glance-2014.1/glance/tests/functional/store/test_rbd.py0000664000175400017540000001174512323736226024257 0ustar jenkinsjenkins00000000000000# Copyright 2013 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ Functional tests for the RBD store interface. Set the GLANCE_TEST_RBD_CONF environment variable to the location of a Glance config that defines how to connect to a functional RBD backend. This backend must be running Ceph Bobtail (0.56) or later. """ import ConfigParser import os import uuid import oslo.config.cfg import six import testtools from glance.common import exception import glance.store.rbd import glance.tests.functional.store as store_tests try: import rados import rbd except ImportError: rados = None def read_config(path): cp = ConfigParser.RawConfigParser() cp.read(path) return cp def parse_config(config): out = {} options = [ 'rbd_store_chunk_size', 'rbd_store_pool', 'rbd_store_user', 'rbd_store_ceph_conf', ] for option in options: out[option] = config.defaults()[option] return out class TestRBDStore(store_tests.BaseTestCase, testtools.TestCase): store_cls_path = 'glance.store.rbd.Store' store_cls = glance.store.rbd.Store store_name = 'rbd' def setUp(self): config_path = os.environ.get('GLANCE_TEST_RBD_CONF') if not config_path: msg = "GLANCE_TEST_RBD_CONF environ not set." self.skipTest(msg) oslo.config.cfg.CONF(args=[], default_config_files=[config_path]) raw_config = read_config(config_path) config = parse_config(raw_config) if rados is None: self.skipTest("rados python library not found") rados_client = rados.Rados(conffile=config['rbd_store_ceph_conf'], rados_id=config['rbd_store_user']) try: rados_client.connect() except rados.Error as e: self.skipTest("Failed to connect to RADOS: %s" % e) try: rados_client.create_pool(config['rbd_store_pool']) except rados.Error as e: rados_client.shutdown() self.skipTest("Failed to create pool: %s") self.rados_client = rados_client self.rbd_config = config super(TestRBDStore, self).setUp() def tearDown(self): self.rados_client.delete_pool(self.rbd_config['rbd_store_pool']) self.rados_client.shutdown() super(TestRBDStore, self).tearDown() def get_store(self, **kwargs): store = glance.store.rbd.Store(context=kwargs.get('context')) store.configure() store.configure_add() return store def stash_image(self, image_id, image_data): fsid = self.rados_client.get_fsid() pool = self.rbd_config['rbd_store_pool'] librbd = rbd.RBD() # image_id must not be unicode since librbd doesn't handle it image_id = str(image_id) snap_name = 'snap' with self.rados_client.open_ioctx(pool) as ioctx: librbd.create(ioctx, image_id, len(image_data), old_format=False, features=rbd.RBD_FEATURE_LAYERING) with rbd.Image(ioctx, image_id) as image: image.write(image_data, 0) image.create_snap(snap_name) return 'rbd://%s/%s/%s/%s' % (fsid, pool, image_id, snap_name) def test_unicode(self): # librbd does not handle unicode, so make sure # all paths through the rbd store convert a unicode image id # and uri to ascii before passing it to librbd. store = self.get_store() image_id = unicode(str(uuid.uuid4())) image_size = 300 image_data = six.StringIO('X' * image_size) image_checksum = '41757066eaff7c4c6c965556b4d3c6c5' uri, add_size, add_checksum = store.add(image_id, image_data, image_size) uri = unicode(uri) self.assertEqual(image_size, add_size) self.assertEqual(image_checksum, add_checksum) location = glance.store.location.Location( self.store_name, store.get_store_location_class(), uri=uri, image_id=image_id) self.assertEqual(image_size, store.get_size(location)) get_iter, get_size = store.get(location) self.assertEqual(image_size, get_size) self.assertEqual('X' * image_size, ''.join(get_iter)) store.delete(location) self.assertRaises(exception.NotFound, store.get, location) glance-2014.1/glance/tests/functional/store/test_vmware_datastore.py0000664000175400017540000001223312323736226027050 0ustar jenkinsjenkins00000000000000# Copyright 2014 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ Functional tests for the VMware Datastore store interface Set the GLANCE_TEST_VMWARE_CONF environment variable to the location of a Glance config that defines how to connect to a functional VMware Datastore backend """ import ConfigParser import httplib import logging import os import oslo.config.cfg from oslo.vmware import api import six.moves.urllib.parse as urlparse import testtools import glance.store.vmware_datastore as vm_store import glance.tests.functional.store as store_tests logging.getLogger('suds').setLevel(logging.INFO) def read_config(path): cp = ConfigParser.RawConfigParser() cp.read(path) return cp def parse_config(config): out = {} options = [ 'vmware_server_host', 'vmware_server_username', 'vmware_server_password', 'vmware_api_retry_count', 'vmware_task_poll_interval', 'vmware_store_image_dir', 'vmware_datacenter_path', 'vmware_datastore_name', 'vmware_api_insecure', ] for option in options: out[option] = config.defaults()[option] return out class VMwareDatastoreStoreError(RuntimeError): pass def vsphere_connect(server_ip, server_username, server_password, api_retry_count, task_poll_interval, scheme='https', create_session=True, wsdl_loc=None): try: return api.VMwareAPISession(server_ip, server_username, server_password, api_retry_count, task_poll_interval, scheme=scheme, create_session=create_session, wsdl_loc=wsdl_loc) except AttributeError: raise VMwareDatastoreStoreError( 'Could not find VMware datastore module') class TestVMwareDatastoreStore(store_tests.BaseTestCase, testtools.TestCase): store_cls_path = 'glance.store.vmware_datastore.Store' store_cls = vm_store.Store store_name = 'vmware_datastore' def _build_vim_cookie_header(self, vim_cookies): """Build ESX host session cookie header.""" if len(list(vim_cookies)) > 0: cookie = list(vim_cookies)[0] return cookie.name + '=' + cookie.value def setUp(self): config_path = os.environ.get('GLANCE_TEST_VMWARE_CONF') if not config_path: msg = 'GLANCE_TEST_VMWARE_CONF environ not set.' self.skipTest(msg) oslo.config.cfg.CONF(args=[], default_config_files=[config_path]) raw_config = read_config(config_path) config = parse_config(raw_config) scheme = 'http' if config['vmware_api_insecure'] == 'True' else 'https' self.vsphere = vsphere_connect(config['vmware_server_host'], config['vmware_server_username'], config['vmware_server_password'], config['vmware_api_retry_count'], config['vmware_task_poll_interval'], scheme=scheme) self.vmware_config = config super(TestVMwareDatastoreStore, self).setUp() def get_store(self, **kwargs): store = vm_store.Store( context=kwargs.get('context')) store.configure() store.configure_add() return store def stash_image(self, image_id, image_data): server_ip = self.vmware_config['vmware_server_host'] path = os.path.join( vm_store.DS_URL_PREFIX, self.vmware_config['vmware_store_image_dir'].strip('/'), image_id) dc_path = self.vmware_config.get('vmware_datacenter_path', 'ha-datacenter') param_list = {'dcPath': dc_path, 'dsName': self.vmware_config['vmware_datastore_name']} query = urlparse.urlencode(param_list) conn = (httplib.HTTPConnection(server_ip) if self.vmware_config['vmware_api_insecure'] == 'True' else httplib.HTTPSConnection(server_ip)) cookie = self._build_vim_cookie_header( self.vsphere.vim.client.options.transport.cookiejar) headers = {'Cookie': cookie, 'Content-Length': len(image_data)} url = urlparse.quote('%s?%s' % (path, query)) conn.request('PUT', url, image_data, headers) conn.getresponse() return '%s://%s%s?%s' % (vm_store.STORE_SCHEME, server_ip, path, query) glance-2014.1/glance/tests/functional/store/test_gridfs.py0000664000175400017540000000462412323736226024764 0ustar jenkinsjenkins00000000000000# Copyright 2013 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 tests for the gridfs store interface Set the GLANCE_TEST_GRIDFS_CONF environment variable to the location of a Glance config that defines how to connect to a functional GridFS backend """ import ConfigParser import os import oslo.config.cfg import testtools import glance.store.gridfs import glance.tests.functional.store as store_tests try: import gridfs import pymongo except ImportError: gridfs = None def read_config(path): cp = ConfigParser.RawConfigParser() cp.read(path) return cp def parse_config(config): out = {} options = [ 'mongodb_store_db', 'mongodb_store_uri'] for option in options: out[option] = config.defaults()[option] return out class TestGridfsStore(store_tests.BaseTestCase, testtools.TestCase): store_cls_path = 'glance.store.gridfs.Store' store_cls = glance.store.gridfs.Store store_name = 'gridfs' def setUp(self): config_path = os.environ.get('GLANCE_TEST_GRIDFS_CONF') if not config_path or not gridfs: msg = "GLANCE_TEST_GRIDFS_CONF environ not set." self.skipTest(msg) oslo.config.cfg.CONF(args=[], default_config_files=[config_path]) raw_config = read_config(config_path) self.gfs_config = parse_config(raw_config) super(TestGridfsStore, self).setUp() def get_store(self, **kwargs): store = self.store_cls(context=kwargs.get('context')) store.configure() store.configure_add() return store def stash_image(self, image_id, image_data): conn = pymongo.MongoClient(self.gfs_config.get("mongodb_store_uri")) fs = gridfs.GridFS(conn[self.gfs_config.get("mongodb_store_db")]) fs.put(image_data, _id=image_id) return 'gridfs://%s' % image_id glance-2014.1/glance/tests/functional/store/__init__.py0000664000175400017540000000761612323736226024212 0ustar jenkinsjenkins00000000000000# Copyright 2012 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import uuid from oslo.config import cfg import six #NOTE(bcwaldon): importing this to get the default_store option import glance.api.v1.images from glance.common import exception import glance.store.location CONF = cfg.CONF class BaseTestCase(object): """ Basic test cases for glance image stores. To run these tests on a new store X, create a test case like class TestXStore(BaseTestCase, testtools.TestCase): (MULTIPLE INHERITANCE REQUIRED) def get_store(...): (STORE SPECIFIC) def stash_image(...): (STORE SPECIFIC) """ def setUp(self): super(BaseTestCase, self).setUp() def tearDown(self): CONF.reset() super(BaseTestCase, self).tearDown() def config(self, **kw): for k, v in kw.iteritems(): CONF.set_override(k, v, group=None) def get_store(self, **kwargs): raise NotImplementedError('get_store() must be implemented') def stash_image(self, image_id, image_data): """Store image data in the backend manually :param image_id: image identifier :param image_data: string representing image data fixture :return URI referencing newly-created backend object """ raise NotImplementedError('stash_image is not implemented') def test_create_store(self): self.config(known_stores=[self.store_cls_path]) count = glance.store.create_stores() self.assertEqual(8, count) def test_lifecycle(self): """Add, get and delete an image""" store = self.get_store() image_id = str(uuid.uuid4()) image_data = six.StringIO('XXX') image_checksum = 'bc9189406be84ec297464a514221406d' try: uri, add_size, add_checksum, _ = store.add(image_id, image_data, 3) except NotImplementedError: msg = 'Configured store can not add images' self.skipTest(msg) self.assertEqual(3, add_size) self.assertEqual(image_checksum, add_checksum) store = self.get_store() location = glance.store.location.Location( self.store_name, store.get_store_location_class(), uri=uri, image_id=image_id) (get_iter, get_size) = store.get(location) self.assertEqual(3, get_size) self.assertEqual('XXX', ''.join(get_iter)) image_size = store.get_size(location) self.assertEqual(3, image_size) store.delete(location) self.assertRaises(exception.NotFound, store.get, location) def test_get_remote_image(self): """Get an image that was created externally to Glance""" image_id = str(uuid.uuid4()) try: image_uri = self.stash_image(image_id, 'XXX') except NotImplementedError: msg = 'Configured store can not stash images' self.skipTest(msg) store = self.get_store() location = glance.store.location.Location( self.store_name, store.get_store_location_class(), uri=image_uri) (get_iter, get_size) = store.get(location) self.assertEqual(3, get_size) self.assertEqual('XXX', ''.join(get_iter)) image_size = store.get_size(location) self.assertEqual(3, image_size) glance-2014.1/glance/tests/functional/test_client_exceptions.py0000664000175400017540000001046112323736226026065 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation # 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 httplib2 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 elif path == "/service-unavailable": request.response = webob.exc.HTTPServiceUnavailable() elif path == "/service-unavailable-retry": request.response.retry_after = 10 request.response.status = 503 elif path == "/expectation-failed": request.response = webob.exc.HTTPExpectationFailed() elif path == "/server-error": request.response = webob.exc.HTTPServerError() elif path == "/server-traceback": raise exception.ServerError() class TestClientExceptions(functional.FunctionalTest): def setUp(self): super(TestClientExceptions, self).setUp() self.port = utils.get_unused_port() server = wsgi.Server() self.config(bind_host='127.0.0.1') self.config(workers=0) server.start(ExceptionTestApp(), 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: if 'retry' in path: self.assertEqual(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) def test_expectation_failed(self): """ Test expectation failed response """ self._do_test_exception('/expectation-failed', exception.UnexpectedStatus) def test_server_error(self): """ Test server error response """ self._do_test_exception('/server-error', exception.ServerError) def test_server_traceback(self): """ Verify that the wsgi server does not return tracebacks to the client on 500 errors (bug 1192132) """ http = httplib2.Http() path = ('http://%s:%d/server-traceback' % ('127.0.0.1', self.port)) response, content = http.request(path, 'GET') self.assertTrue('ServerError' not in content) self.assertEqual(response.status, 500) glance-2014.1/glance/tests/functional/test_scrubber.py0000664000175400017540000003760412323736226024165 0ustar jenkinsjenkins00000000000000# Copyright 2011-2012 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import os import sys import time import httplib2 from six.moves import xrange import swiftclient from glance.common import crypt from glance.openstack.common import jsonutils from glance.openstack.common import units from glance.store.swift import StoreLocation from glance.tests import functional from glance.tests.functional.store.test_swift import parse_config from glance.tests.functional.store.test_swift import read_config from glance.tests.functional.store.test_swift import swift_connect from glance.tests.utils import execute TEST_IMAGE_DATA = '*' * 5 * units.Ki TEST_IMAGE_META = { 'name': 'test_image', 'is_public': False, 'disk_format': 'raw', 'container_format': 'ovf', } class TestScrubber(functional.FunctionalTest): """Test that delayed_delete works and the scrubber deletes""" def test_delayed_delete(self): """ test that images don't get deleted immediately and that the scrubber scrubs them """ self.cleanup() self.start_servers(delayed_delete=True, daemon=True) headers = { 'x-image-meta-name': 'test_image', 'x-image-meta-is_public': 'true', 'x-image-meta-disk_format': 'raw', 'x-image-meta-container_format': 'ovf', 'content-type': 'application/octet-stream', } path = "http://%s:%d/v1/images" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, 'POST', body='XXX', headers=headers) self.assertEqual(response.status, 201) image = jsonutils.loads(content)['image'] self.assertEqual('active', image['status']) image_id = image['id'] path = "http://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port, image_id) http = httplib2.Http() response, content = http.request(path, 'DELETE') self.assertEqual(response.status, 200) response, content = http.request(path, 'HEAD') self.assertEqual(response.status, 200) self.assertEqual('pending_delete', response['x-image-meta-status']) self.wait_for_scrub(path) self.stop_servers() def test_scrubber_app(self): """ test that the glance-scrubber script runs successfully when not in daemon mode """ self.cleanup() self.start_servers(delayed_delete=True, daemon=False) headers = { 'x-image-meta-name': 'test_image', 'x-image-meta-is_public': 'true', 'x-image-meta-disk_format': 'raw', 'x-image-meta-container_format': 'ovf', 'content-type': 'application/octet-stream', } path = "http://%s:%d/v1/images" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, 'POST', body='XXX', headers=headers) self.assertEqual(response.status, 201) image = jsonutils.loads(content)['image'] self.assertEqual('active', image['status']) image_id = image['id'] path = "http://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port, image_id) http = httplib2.Http() response, content = http.request(path, 'DELETE') self.assertEqual(response.status, 200) response, content = http.request(path, 'HEAD') self.assertEqual(response.status, 200) self.assertEqual('pending_delete', response['x-image-meta-status']) # wait for the scrub time on the image to pass time.sleep(self.api_server.scrub_time) # scrub images and make sure they get deleted exe_cmd = "%s -m glance.cmd.scrubber" % sys.executable cmd = ("%s --config-file %s" % (exe_cmd, self.scrubber_daemon.conf_file_name)) exitcode, out, err = execute(cmd, raise_error=False) self.assertEqual(0, exitcode) self.wait_for_scrub(path) self.stop_servers() def test_scrubber_app_against_swift(self): """ test that the glance-scrubber script runs successfully against a swift backend when not in daemon mode """ config_path = os.environ.get('GLANCE_TEST_SWIFT_CONF') if not config_path: msg = "GLANCE_TEST_SWIFT_CONF environ not set." self.skipTest(msg) raw_config = read_config(config_path) swift_config = parse_config(raw_config) self.cleanup() self.start_servers(delayed_delete=True, daemon=False, default_store='swift', **swift_config) # add an image headers = { 'x-image-meta-name': 'test_image', 'x-image-meta-is_public': 'true', 'x-image-meta-disk_format': 'raw', 'x-image-meta-container_format': 'ovf', 'content-type': 'application/octet-stream', } path = "http://%s:%d/v1/images" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, 'POST', body='XXX', headers=headers) # ensure the request was successful and the image is active self.assertEqual(response.status, 201) image = jsonutils.loads(content)['image'] self.assertEqual('active', image['status']) image_id = image['id'] # delete the image path = "http://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port, image_id) http = httplib2.Http() response, content = http.request(path, 'DELETE') self.assertEqual(response.status, 200) # ensure the image is marked pending delete response, content = http.request(path, 'HEAD') self.assertEqual(response.status, 200) self.assertEqual('pending_delete', response['x-image-meta-status']) # wait for the scrub time on the image to pass time.sleep(self.api_server.scrub_time) # call the scrubber to scrub images exe_cmd = "%s -m glance.cmd.scrubber" % sys.executable cmd = ("%s --config-file %s" % (exe_cmd, self.scrubber_daemon.conf_file_name)) exitcode, out, err = execute(cmd, raise_error=False) self.assertEqual(0, exitcode) # ensure the image has been successfully deleted self.wait_for_scrub(path) self.stop_servers() def test_scrubber_with_metadata_enc(self): """ test that files written to scrubber_data_dir use metadata_encryption_key when available to encrypt the location """ config_path = os.environ.get('GLANCE_TEST_SWIFT_CONF') if not config_path: msg = "GLANCE_TEST_SWIFT_CONF environ not set." self.skipTest(msg) raw_config = read_config(config_path) swift_config = parse_config(raw_config) self.cleanup() self.start_servers(delayed_delete=True, daemon=True, default_store='swift', **swift_config) # add an image headers = { 'x-image-meta-name': 'test_image', 'x-image-meta-is_public': 'true', 'x-image-meta-disk_format': 'raw', 'x-image-meta-container_format': 'ovf', 'content-type': 'application/octet-stream', } path = "http://%s:%d/v1/images" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, 'POST', body='XXX', headers=headers) self.assertEqual(response.status, 201) image = jsonutils.loads(content)['image'] self.assertEqual('active', image['status']) image_id = image['id'] # delete the image path = "http://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port, image_id) http = httplib2.Http() response, content = http.request(path, 'DELETE') self.assertEqual(response.status, 200) response, content = http.request(path, 'HEAD') self.assertEqual(response.status, 200) self.assertEqual('pending_delete', response['x-image-meta-status']) # ensure the marker file has encrypted the image location by decrypting # it and checking the image_id is intact file_path = os.path.join(self.api_server.scrubber_datadir, str(image_id)) marker_uri = None with open(file_path, 'r') as f: marker_uri = f.readline().strip() self.assertTrue(marker_uri is not None) decrypted_uri = crypt.urlsafe_decrypt( self.api_server.metadata_encryption_key, marker_uri) loc = StoreLocation({}) loc.parse_uri(decrypted_uri) self.assertIn(loc.scheme, ("swift+http", "swift+https")) self.assertEqual(image['id'], loc.obj) self.wait_for_scrub(path) self.stop_servers() def test_scrubber_handles_swift_missing(self): """ Test that the scrubber handles the case where the image to be scrubbed is missing from swift """ config_path = os.environ.get('GLANCE_TEST_SWIFT_CONF') if not config_path: msg = "GLANCE_TEST_SWIFT_CONF environ not set." self.skipTest(msg) raw_config = read_config(config_path) swift_config = parse_config(raw_config) self.cleanup() self.start_servers(delayed_delete=True, daemon=False, default_store='swift', **swift_config) # add an image headers = { 'x-image-meta-name': 'test_image', 'x-image-meta-is_public': 'true', 'x-image-meta-disk_format': 'raw', 'x-image-meta-container_format': 'ovf', 'content-type': 'application/octet-stream', } path = "http://%s:%d/v1/images" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, 'POST', body='XXX', headers=headers) self.assertEqual(response.status, 201) image = jsonutils.loads(content)['image'] self.assertEqual('active', image['status']) image_id = image['id'] # delete the image path = "http://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port, image_id) http = httplib2.Http() response, content = http.request(path, 'DELETE') self.assertEqual(response.status, 200) # ensure the image is marked pending delete response, content = http.request(path, 'HEAD') self.assertEqual(response.status, 200) self.assertEqual('pending_delete', response['x-image-meta-status']) # go directly to swift and remove the image object swift = swift_connect(swift_config['swift_store_auth_address'], swift_config['swift_store_auth_version'], swift_config['swift_store_user'], swift_config['swift_store_key']) swift.delete_object(swift_config['swift_store_container'], image_id) try: swift.head_object(swift_config['swift_store_container'], image_id) self.fail('image should have been deleted from swift') except swiftclient.ClientException as e: self.assertEqual(e.http_status, 404) # wait for the scrub time on the image to pass time.sleep(self.api_server.scrub_time) # run the scrubber app, and ensure it doesn't fall over exe_cmd = "%s -m glance.cmd.scrubber" % sys.executable cmd = ("%s --config-file %s" % (exe_cmd, self.scrubber_daemon.conf_file_name)) exitcode, out, err = execute(cmd, raise_error=False) self.assertEqual(0, exitcode) self.wait_for_scrub(path) self.stop_servers() def test_scrubber_delete_handles_exception(self): """ Test that the scrubber handles the case where an exception occurs when _delete() is called. The scrubber should not write out queue files in this case. """ # Start servers. self.cleanup() self.start_servers(delayed_delete=True, daemon=False, default_store='file') # Check that we are using a file backend. self.assertEqual(self.api_server.default_store, 'file') # add an image headers = { 'x-image-meta-name': 'test_image', 'x-image-meta-is_public': 'true', 'x-image-meta-disk_format': 'raw', 'x-image-meta-container_format': 'ovf', 'content-type': 'application/octet-stream', } path = "http://%s:%d/v1/images" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, 'POST', body='XXX', headers=headers) self.assertEqual(response.status, 201) image = jsonutils.loads(content)['image'] self.assertEqual('active', image['status']) image_id = image['id'] # delete the image path = "http://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port, image_id) http = httplib2.Http() response, content = http.request(path, 'DELETE') self.assertEqual(response.status, 200) # ensure the image is marked pending delete response, content = http.request(path, 'HEAD') self.assertEqual(response.status, 200) self.assertEqual('pending_delete', response['x-image-meta-status']) # Remove the file from the backend. file_path = os.path.join(self.api_server.image_dir, str(image_id)) os.remove(file_path) # Wait for the scrub time on the image to pass time.sleep(self.api_server.scrub_time) # run the scrubber app, and ensure it doesn't fall over exe_cmd = "%s -m glance.cmd.scrubber" % sys.executable cmd = ("%s --config-file %s" % (exe_cmd, self.scrubber_daemon.conf_file_name)) exitcode, out, err = execute(cmd, raise_error=False) self.assertEqual(0, exitcode) self.wait_for_scrub(path) # Make sure there are no queue files associated with image. queue_file_path = os.path.join(self.api_server.scrubber_datadir, str(image_id)) self.assertFalse(os.path.exists(queue_file_path)) self.stop_servers() def wait_for_scrub(self, path): """ NOTE(jkoelker) The build servers sometimes take longer than 15 seconds to scrub. Give it up to 5 min, checking checking every 15 seconds. When/if it flips to deleted, bail immediately. """ http = httplib2.Http() wait_for = 300 # seconds check_every = 15 # seconds for _ in xrange(wait_for / check_every): time.sleep(check_every) response, content = http.request(path, 'HEAD') if (response['x-image-meta-status'] == 'deleted' and response['x-image-meta-deleted'] == 'True'): break else: continue else: self.fail('image was never scrubbed') glance-2014.1/glance/tests/functional/test_client_redirects.py0000664000175400017540000001156212323736226025673 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """Functional test cases testing glance client redirect-following.""" 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) def RedirectTestApp(name): class App(object): """ Test WSGI application which can respond with multiple kinds of HTTP redirects and is used to verify Glance client redirects. """ def __init__(self): """ Initialize app with a name and port. """ self.name = name @webob.dec.wsgify def __call__(self, request): """ Handles all requests to the application. """ base = "http://%s" % request.host path = request.path_qs if path == "/": return "root" elif path == "/302": url = "%s/success" % base raise webob.exc.HTTPFound(location=url) elif path == "/302?with_qs=yes": url = "%s/success?with_qs=yes" % base raise webob.exc.HTTPFound(location=url) elif path == "/infinite_302": raise webob.exc.HTTPFound(location=request.url) elif path.startswith("/redirect-to"): url = "http://127.0.0.1:%s/success" % path.split("-")[-1] raise webob.exc.HTTPFound(location=url) elif path == "/success": return "success_from_host_%s" % self.name elif path == "/success?with_qs=yes": return "success_with_qs" return "fail" return App class TestClientRedirects(functional.FunctionalTest): def setUp(self): super(TestClientRedirects, self).setUp() self.port_one = utils.get_unused_port() self.port_two = utils.get_unused_port() server_one = wsgi.Server() server_two = wsgi.Server() self.config(bind_host='127.0.0.1') self.config(workers=0) server_one.start(RedirectTestApp("one")(), self.port_one) server_two.start(RedirectTestApp("two")(), self.port_two) self.client = client.BaseClient("127.0.0.1", self.port_one) def test_get_without_redirect(self): """ Test GET with no redirect """ response = self.client.do_request("GET", "/") self.assertEqual(200, response.status) self.assertEqual("root", response.read()) def test_get_with_one_redirect(self): """ Test GET with one 302 FOUND redirect """ response = self.client.do_request("GET", "/302") self.assertEqual(200, response.status) self.assertEqual("success_from_host_one", response.read()) def test_get_with_one_redirect_query_string(self): """ Test GET with one 302 FOUND redirect w/ a query string """ response = self.client.do_request("GET", "/302", params={'with_qs': 'yes'}) self.assertEqual(200, response.status) self.assertEqual("success_with_qs", response.read()) def test_get_with_max_redirects(self): """ Test we don't redirect forever. """ self.assertRaises(exception.MaxRedirectsExceeded, self.client.do_request, "GET", "/infinite_302") def test_post_redirect(self): """ Test POST with 302 redirect """ response = self.client.do_request("POST", "/302") self.assertEqual(200, response.status) self.assertEqual("success_from_host_one", response.read()) def test_redirect_to_new_host(self): """ Test redirect to one host and then another. """ url = "/redirect-to-%d" % self.port_two response = self.client.do_request("POST", url) self.assertEqual(200, response.status) self.assertEqual("success_from_host_two", response.read()) response = self.client.do_request("POST", "/success") self.assertEqual(200, response.status) self.assertEqual("success_from_host_one", response.read()) glance-2014.1/glance/tests/functional/test_logging.py0000664000175400017540000000570712323736226024003 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """Functional test case that tests logging output""" import httplib2 import os import stat from glance.tests import functional class TestLogging(functional.FunctionalTest): """Functional tests for Glance's logging output""" def test_verbose_debug(self): """ Test logging output proper when verbose and debug is on. """ self.cleanup() self.start_servers() # The default functional test case has both verbose # and debug on. Let's verify that debug statements # appear in both the API and registry logs. self.assertTrue(os.path.exists(self.api_server.log_file)) api_log_out = open(self.api_server.log_file, 'r').read() self.assertTrue('DEBUG glance' in api_log_out) self.assertTrue(os.path.exists(self.registry_server.log_file)) registry_log_out = open(self.registry_server.log_file, 'r').read() self.assertTrue('DEBUG glance' in registry_log_out) self.stop_servers() def test_no_verbose_no_debug(self): """ Test logging output proper when verbose and debug is off. """ self.cleanup() self.start_servers(debug=False, verbose=False) self.assertTrue(os.path.exists(self.api_server.log_file)) api_log_out = open(self.api_server.log_file, 'r').read() self.assertFalse('DEBUG glance' in api_log_out) self.assertTrue(os.path.exists(self.registry_server.log_file)) registry_log_out = open(self.registry_server.log_file, 'r').read() self.assertFalse('DEBUG glance' in registry_log_out) self.stop_servers() def assertNotEmptyFile(self, path): self.assertTrue(os.path.exists(path)) self.assertNotEqual(os.stat(path)[stat.ST_SIZE], 0) def test_logrotate(self): """ Test that we notice when our log file has been rotated """ self.cleanup() self.start_servers() self.assertNotEmptyFile(self.api_server.log_file) os.rename(self.api_server.log_file, self.api_server.log_file + ".1") path = "http://%s:%d/" % ("127.0.0.1", self.api_port) response, content = httplib2.Http().request(path, 'GET') self.assertEqual(response.status, 300) self.assertNotEmptyFile(self.api_server.log_file) self.stop_servers() glance-2014.1/glance/tests/functional/test_gzip_middleware.py0000664000175400017540000000323112323736226025511 0ustar jenkinsjenkins00000000000000# Copyright 2013 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. """Tests gzip middleware.""" import httplib2 from glance.tests import functional from glance.tests import utils class GzipMiddlewareTest(functional.FunctionalTest): @utils.skip_if_disabled def test_gzip_requests(self): self.cleanup() self.start_servers(**self.__dict__.copy()) def request(path, headers=None): # We don't care what version we're using here so, # sticking with latest url = 'http://127.0.0.1:%s/v2/%s' % (self.api_port, path) http = httplib2.Http() return http.request(url, 'GET', headers=headers) # Accept-Encoding: Identity headers = {'Accept-Encoding': 'identity'} response, content = request('images', headers=headers) self.assertIsNone(response.get("-content-encoding")) # Accept-Encoding: gzip headers = {'Accept-Encoding': 'gzip'} response, content = request('images', headers=headers) self.assertEqual(response.get("-content-encoding"), 'gzip') self.stop_servers() glance-2014.1/glance/tests/functional/test_sqlite.py0000664000175400017540000000250612323736226023650 0ustar jenkinsjenkins00000000000000# 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 cases for sqlite-specific logic""" from glance.tests import functional from glance.tests.utils import depends_on_exe from glance.tests.utils import execute from glance.tests.utils import skip_if_disabled class TestSqlite(functional.FunctionalTest): """Functional tests for sqlite-specific logic""" @depends_on_exe('sqlite3') @skip_if_disabled def test_big_int_mapping(self): """Ensure BigInteger not mapped to BIGINT""" self.cleanup() self.start_servers(**self.__dict__.copy()) cmd = "sqlite3 tests.sqlite '.schema'" exitcode, out, err = execute(cmd, raise_error=True) self.assertFalse('BIGINT' in out) self.stop_servers() glance-2014.1/glance/tests/functional/v2/0000775000175400017540000000000012323736427021265 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/tests/functional/v2/test_images.py0000664000175400017540000033372612323736226024156 0ustar jenkinsjenkins00000000000000# Copyright 2012 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import os import signal import tempfile import uuid import requests from glance.openstack.common import jsonutils from glance.tests import functional from glance.tests.functional.store import test_http TENANT1 = str(uuid.uuid4()) TENANT2 = str(uuid.uuid4()) TENANT3 = str(uuid.uuid4()) TENANT4 = str(uuid.uuid4()) class TestImages(functional.FunctionalTest): def setUp(self): super(TestImages, self).setUp() self.cleanup() self.api_server.deployment_flavor = 'noauth' self.start_servers(**self.__dict__.copy()) def _url(self, path): return 'http://127.0.0.1:%d%s' % (self.api_port, path) def _headers(self, custom_headers=None): base_headers = { 'X-Identity-Status': 'Confirmed', 'X-Auth-Token': '932c5c84-02ac-4fe5-a9ba-620af0e2bb96', 'X-User-Id': 'f9a41d13-0c13-47e9-bee2-ce4e8bfe958e', 'X-Tenant-Id': TENANT1, 'X-Roles': 'member', } base_headers.update(custom_headers or {}) return base_headers def test_image_lifecycle(self): # Image list should be empty path = self._url('/v2/images') response = requests.get(path, headers=self._headers()) self.assertEqual(200, response.status_code) images = jsonutils.loads(response.text)['images'] self.assertEqual(0, len(images)) # Create an image (with two deployer-defined properties) path = self._url('/v2/images') headers = self._headers({'content-type': 'application/json'}) data = jsonutils.dumps({'name': 'image-1', 'type': 'kernel', 'foo': 'bar', 'disk_format': 'aki', 'container_format': 'aki', 'abc': 'xyz'}) response = requests.post(path, headers=headers, data=data) self.assertEqual(201, response.status_code) image_location_header = response.headers['Location'] # Returned image entity should have a generated id and status image = jsonutils.loads(response.text) image_id = image['id'] checked_keys = set([ u'status', u'name', u'tags', u'created_at', u'updated_at', u'visibility', u'self', u'protected', u'id', u'file', u'min_disk', u'foo', u'abc', u'type', u'min_ram', u'schema', u'disk_format', u'container_format', u'owner', ]) self.assertEqual(set(image.keys()), checked_keys) expected_image = { 'status': 'queued', 'name': 'image-1', 'tags': [], 'visibility': 'private', 'self': '/v2/images/%s' % image_id, 'protected': False, 'file': '/v2/images/%s/file' % image_id, 'min_disk': 0, 'foo': 'bar', 'abc': 'xyz', 'type': 'kernel', 'min_ram': 0, 'schema': '/v2/schemas/image', } for key, value in expected_image.items(): self.assertEqual(image[key], value, key) # Image list should now have one entry path = self._url('/v2/images') response = requests.get(path, headers=self._headers()) self.assertEqual(200, response.status_code) images = jsonutils.loads(response.text)['images'] self.assertEqual(1, len(images)) self.assertEqual(images[0]['id'], image_id) # Create another image (with two deployer-defined properties) path = self._url('/v2/images') headers = self._headers({'content-type': 'application/json'}) data = jsonutils.dumps({'name': 'image-2', 'type': 'kernel', 'bar': 'foo', 'disk_format': 'aki', 'container_format': 'aki', 'xyz': 'abc'}) response = requests.post(path, headers=headers, data=data) self.assertEqual(201, response.status_code) # Returned image entity should have a generated id and status image = jsonutils.loads(response.text) image2_id = image['id'] checked_keys = set([ u'status', u'name', u'tags', u'created_at', u'updated_at', u'visibility', u'self', u'protected', u'id', u'file', u'min_disk', u'bar', u'xyz', u'type', u'min_ram', u'schema', u'disk_format', u'container_format', u'owner', ]) self.assertEqual(set(image.keys()), checked_keys) expected_image = { 'status': 'queued', 'name': 'image-2', 'tags': [], 'visibility': 'private', 'self': '/v2/images/%s' % image2_id, 'protected': False, 'file': '/v2/images/%s/file' % image2_id, 'min_disk': 0, 'bar': 'foo', 'xyz': 'abc', 'type': 'kernel', 'min_ram': 0, 'schema': '/v2/schemas/image', } for key, value in expected_image.items(): self.assertEqual(image[key], value, key) # Image list should now have two entries path = self._url('/v2/images') response = requests.get(path, headers=self._headers()) self.assertEqual(200, response.status_code) images = jsonutils.loads(response.text)['images'] self.assertEqual(2, len(images)) self.assertEqual(images[0]['id'], image2_id) self.assertEqual(images[1]['id'], image_id) # Image list should list only image-2 as image-1 doesn't contain the # property 'bar' path = self._url('/v2/images?bar=foo') response = requests.get(path, headers=self._headers()) self.assertEqual(200, response.status_code) images = jsonutils.loads(response.text)['images'] self.assertEqual(1, len(images)) self.assertEqual(images[0]['id'], image2_id) # Image list should list only image-1 as image-2 doesn't contain the # property 'foo' path = self._url('/v2/images?foo=bar') response = requests.get(path, headers=self._headers()) self.assertEqual(200, response.status_code) images = jsonutils.loads(response.text)['images'] self.assertEqual(1, len(images)) self.assertEqual(images[0]['id'], image_id) # Image list should list only image-1 based on the filter # 'foo=bar&abc=xyz' path = self._url('/v2/images?foo=bar&abc=xyz') response = requests.get(path, headers=self._headers()) self.assertEqual(200, response.status_code) images = jsonutils.loads(response.text)['images'] self.assertEqual(1, len(images)) self.assertEqual(images[0]['id'], image_id) # Image list should list only image-2 based on the filter # 'bar=foo&xyz=abc' path = self._url('/v2/images?bar=foo&xyz=abc') response = requests.get(path, headers=self._headers()) self.assertEqual(200, response.status_code) images = jsonutils.loads(response.text)['images'] self.assertEqual(1, len(images)) self.assertEqual(images[0]['id'], image2_id) # Image list should not list anything as the filter 'foo=baz&abc=xyz' # is not satisfied by either images path = self._url('/v2/images?foo=baz&abc=xyz') response = requests.get(path, headers=self._headers()) self.assertEqual(200, response.status_code) images = jsonutils.loads(response.text)['images'] self.assertEqual(0, len(images)) # Get the image using the returned Location header response = requests.get(image_location_header, headers=self._headers()) self.assertEqual(200, response.status_code) image = jsonutils.loads(response.text) self.assertEqual(image_id, image['id']) self.assertFalse('checksum' in image) self.assertNotIn('size', image) self.assertNotIn('virtual_size', image) self.assertEqual('bar', image['foo']) self.assertEqual(False, image['protected']) self.assertEqual('kernel', image['type']) self.assertTrue(image['created_at']) self.assertTrue(image['updated_at']) self.assertEqual(image['updated_at'], image['created_at']) # The image should be mutable, including adding and removing properties path = self._url('/v2/images/%s' % image_id) media_type = 'application/openstack-images-v2.1-json-patch' headers = self._headers({'content-type': media_type}) data = jsonutils.dumps([ {'op': 'replace', 'path': '/name', 'value': 'image-2'}, {'op': 'replace', 'path': '/disk_format', 'value': 'vhd'}, {'op': 'replace', 'path': '/container_format', 'value': 'ami'}, {'op': 'replace', 'path': '/foo', 'value': 'baz'}, {'op': 'add', 'path': '/ping', 'value': 'pong'}, {'op': 'replace', 'path': '/protected', 'value': True}, {'op': 'remove', 'path': '/type'}, ]) response = requests.patch(path, headers=headers, data=data) self.assertEqual(200, response.status_code, response.text) # Returned image entity should reflect the changes image = jsonutils.loads(response.text) self.assertEqual('image-2', image['name']) self.assertEqual('vhd', image['disk_format']) self.assertEqual('baz', image['foo']) self.assertEqual('pong', image['ping']) self.assertTrue(image['protected']) self.assertFalse('type' in image, response.text) # Adding 11 image properties should fail since configured limit is 10 path = self._url('/v2/images/%s' % image_id) media_type = 'application/openstack-images-v2.1-json-patch' headers = self._headers({'content-type': media_type}) changes = [] for i in range(11): changes.append({'op': 'add', 'path': '/ping%i' % i, 'value': 'pong'}) data = jsonutils.dumps(changes) response = requests.patch(path, headers=headers, data=data) self.assertEqual(413, response.status_code, response.text) # Adding 3 image locations should fail since configured limit is 2 for i in range(3): file_path = os.path.join(self.test_dir, 'fake_image_%i' % i) with open(file_path, 'w') as fap: fap.write('glance') path = self._url('/v2/images/%s' % image_id) media_type = 'application/openstack-images-v2.1-json-patch' headers = self._headers({'content-type': media_type}) changes = [] for i in range(3): changes.append({'op': 'add', 'path': '/locations/-', 'value': {'url': 'file://{0}'.format( os.path.join(self.test_dir, 'fake_image_%i' % i)), 'metadata': {}}, }) data = jsonutils.dumps(changes) response = requests.patch(path, headers=headers, data=data) self.assertEqual(413, response.status_code, response.text) # Ensure the v2.0 json-patch content type is accepted path = self._url('/v2/images/%s' % image_id) media_type = 'application/openstack-images-v2.0-json-patch' headers = self._headers({'content-type': media_type}) data = jsonutils.dumps([{'add': '/ding', 'value': 'dong'}]) response = requests.patch(path, headers=headers, data=data) self.assertEqual(200, response.status_code, response.text) # Returned image entity should reflect the changes image = jsonutils.loads(response.text) self.assertEqual('dong', image['ding']) # Updates should persist across requests path = self._url('/v2/images/%s' % image_id) response = requests.get(path, headers=self._headers()) self.assertEqual(200, response.status_code) image = jsonutils.loads(response.text) self.assertEqual(image_id, image['id']) self.assertEqual('image-2', image['name']) self.assertEqual('baz', image['foo']) self.assertEqual('pong', image['ping']) self.assertTrue(image['protected']) self.assertFalse('type' in image, response.text) # Try to download data before its uploaded path = self._url('/v2/images/%s/file' % image_id) headers = self._headers() response = requests.get(path, headers=headers) self.assertEqual(204, response.status_code) def _verify_image_checksum_and_status(checksum, status): # Checksum should be populated and status should be active path = self._url('/v2/images/%s' % image_id) response = requests.get(path, headers=self._headers()) self.assertEqual(200, response.status_code) image = jsonutils.loads(response.text) self.assertEqual(checksum, image['checksum']) self.assertEqual(status, image['status']) # Upload some image data path = self._url('/v2/images/%s/file' % image_id) headers = self._headers({'Content-Type': 'application/octet-stream'}) response = requests.put(path, headers=headers, data='ZZZZZ') self.assertEqual(204, response.status_code) expected_checksum = '8f113e38d28a79a5a451b16048cc2b72' _verify_image_checksum_and_status(expected_checksum, 'active') # `disk_format` and `container_format` cannot # be replaced when the image is active. immutable_paths = ['/disk_format', '/container_format'] media_type = 'application/openstack-images-v2.1-json-patch' headers = self._headers({'content-type': media_type}) path = self._url('/v2/images/%s' % image_id) for immutable_path in immutable_paths: data = jsonutils.dumps([ {'op': 'replace', 'path': immutable_path, 'value': 'ari'}, ]) response = requests.patch(path, headers=headers, data=data) self.assertEqual(403, response.status_code) # Try to download the data that was just uploaded path = self._url('/v2/images/%s/file' % image_id) response = requests.get(path, headers=self._headers()) self.assertEqual(200, response.status_code) self.assertEqual(expected_checksum, response.headers['Content-MD5']) self.assertEqual(response.text, 'ZZZZZ') # Uploading duplicate data should be rejected with a 409. The # original data should remain untouched. path = self._url('/v2/images/%s/file' % image_id) headers = self._headers({'Content-Type': 'application/octet-stream'}) response = requests.put(path, headers=headers, data='XXX') self.assertEqual(409, response.status_code) _verify_image_checksum_and_status(expected_checksum, 'active') # Ensure the size is updated to reflect the data uploaded path = self._url('/v2/images/%s' % image_id) response = requests.get(path, headers=self._headers()) self.assertEqual(200, response.status_code) self.assertEqual(5, jsonutils.loads(response.text)['size']) # Deletion should not work on protected images path = self._url('/v2/images/%s' % image_id) response = requests.delete(path, headers=self._headers()) self.assertEqual(403, response.status_code) # Unprotect image for deletion path = self._url('/v2/images/%s' % image_id) media_type = 'application/openstack-images-v2.1-json-patch' headers = self._headers({'content-type': media_type}) doc = [{'op': 'replace', 'path': '/protected', 'value': False}] data = jsonutils.dumps(doc) response = requests.patch(path, headers=headers, data=data) self.assertEqual(200, response.status_code, response.text) # Remove all locations of the image then the image size shouldn't be # able to access path = self._url('/v2/images/%s' % image2_id) media_type = 'application/openstack-images-v2.1-json-patch' headers = self._headers({'content-type': media_type}) doc = [{'op': 'replace', 'path': '/locations', 'value': []}] data = jsonutils.dumps(doc) response = requests.patch(path, headers=headers, data=data) self.assertEqual(200, response.status_code, response.text) image = jsonutils.loads(response.text) self.assertNotIn('size', image) self.assertNotIn('virtual_size', image) self.assertEqual('queued', image['status']) # Deletion should work. Deleting image-1 path = self._url('/v2/images/%s' % image_id) response = requests.delete(path, headers=self._headers()) self.assertEqual(204, response.status_code) # This image should be no longer be directly accessible path = self._url('/v2/images/%s' % image_id) response = requests.get(path, headers=self._headers()) self.assertEqual(404, response.status_code) # And neither should its data path = self._url('/v2/images/%s/file' % image_id) headers = self._headers() response = requests.get(path, headers=headers) self.assertEqual(404, response.status_code) # Image list should now contain just image-2 path = self._url('/v2/images') response = requests.get(path, headers=self._headers()) self.assertEqual(200, response.status_code) images = jsonutils.loads(response.text)['images'] self.assertEqual(1, len(images)) self.assertEqual(images[0]['id'], image2_id) # Deleting image-2 should work path = self._url('/v2/images/%s' % image2_id) response = requests.delete(path, headers=self._headers()) self.assertEqual(204, response.status_code) # Image list should now be empty path = self._url('/v2/images') response = requests.get(path, headers=self._headers()) self.assertEqual(200, response.status_code) images = jsonutils.loads(response.text)['images'] self.assertEqual(0, len(images)) self.stop_servers() def test_permissions(self): # Create an image that belongs to TENANT1 path = self._url('/v2/images') headers = self._headers({'Content-Type': 'application/json'}) data = jsonutils.dumps({'name': 'image-1', 'disk_format': 'raw', 'container_format': 'bare'}) response = requests.post(path, headers=headers, data=data) self.assertEqual(201, response.status_code) image_id = jsonutils.loads(response.text)['id'] # Upload some image data path = self._url('/v2/images/%s/file' % image_id) headers = self._headers({'Content-Type': 'application/octet-stream'}) response = requests.put(path, headers=headers, data='ZZZZZ') self.assertEqual(204, response.status_code) # TENANT1 should see the image in their list path = self._url('/v2/images') response = requests.get(path, headers=self._headers()) self.assertEqual(200, response.status_code) images = jsonutils.loads(response.text)['images'] self.assertEqual(image_id, images[0]['id']) # TENANT1 should be able to access the image directly path = self._url('/v2/images/%s' % image_id) response = requests.get(path, headers=self._headers()) self.assertEqual(200, response.status_code) # TENANT2 should not see the image in their list path = self._url('/v2/images') headers = self._headers({'X-Tenant-Id': TENANT2}) response = requests.get(path, headers=headers) self.assertEqual(200, response.status_code) images = jsonutils.loads(response.text)['images'] self.assertEqual(0, len(images)) # TENANT2 should not be able to access the image directly path = self._url('/v2/images/%s' % image_id) headers = self._headers({'X-Tenant-Id': TENANT2}) response = requests.get(path, headers=headers) self.assertEqual(404, response.status_code) # TENANT2 should not be able to modify the image, either path = self._url('/v2/images/%s' % image_id) headers = self._headers({ 'Content-Type': 'application/openstack-images-v2.1-json-patch', 'X-Tenant-Id': TENANT2, }) doc = [{'op': 'replace', 'path': '/name', 'value': 'image-2'}] data = jsonutils.dumps(doc) response = requests.patch(path, headers=headers, data=data) self.assertEqual(404, response.status_code) # TENANT2 should not be able to delete the image, either path = self._url('/v2/images/%s' % image_id) headers = self._headers({'X-Tenant-Id': TENANT2}) response = requests.delete(path, headers=headers) self.assertEqual(404, response.status_code) # Publicize the image as an admin of TENANT1 path = self._url('/v2/images/%s' % image_id) headers = self._headers({ 'Content-Type': 'application/openstack-images-v2.1-json-patch', 'X-Roles': 'admin', }) doc = [{'op': 'replace', 'path': '/visibility', 'value': 'public'}] data = jsonutils.dumps(doc) response = requests.patch(path, headers=headers, data=data) self.assertEqual(200, response.status_code) # TENANT3 should now see the image in their list path = self._url('/v2/images') headers = self._headers({'X-Tenant-Id': TENANT3}) response = requests.get(path, headers=headers) self.assertEqual(200, response.status_code) images = jsonutils.loads(response.text)['images'] self.assertEqual(image_id, images[0]['id']) # TENANT3 should also be able to access the image directly path = self._url('/v2/images/%s' % image_id) headers = self._headers({'X-Tenant-Id': TENANT3}) response = requests.get(path, headers=headers) self.assertEqual(200, response.status_code) # TENANT3 still should not be able to modify the image path = self._url('/v2/images/%s' % image_id) headers = self._headers({ 'Content-Type': 'application/openstack-images-v2.1-json-patch', 'X-Tenant-Id': TENANT3, }) doc = [{'op': 'replace', 'path': '/name', 'value': 'image-2'}] data = jsonutils.dumps(doc) response = requests.patch(path, headers=headers, data=data) self.assertEqual(403, response.status_code) # TENANT3 should not be able to delete the image, either path = self._url('/v2/images/%s' % image_id) headers = self._headers({'X-Tenant-Id': TENANT3}) response = requests.delete(path, headers=headers) self.assertEqual(403, response.status_code) # Image data should still be present after the failed delete path = self._url('/v2/images/%s/file' % image_id) response = requests.get(path, headers=self._headers()) self.assertEqual(200, response.status_code) self.assertEqual(response.text, 'ZZZZZ') self.stop_servers() def test_property_protections_with_roles(self): # Enable property protection self.api_server.property_protection_file = self.property_file_roles self.start_servers(**self.__dict__.copy()) # Image list should be empty path = self._url('/v2/images') response = requests.get(path, headers=self._headers()) self.assertEqual(200, response.status_code) images = jsonutils.loads(response.text)['images'] self.assertEqual(0, len(images)) ## Create an image for role member with extra props # Raises 403 since user is not allowed to set 'foo' path = self._url('/v2/images') headers = self._headers({'content-type': 'application/json', 'X-Roles': 'member'}) data = jsonutils.dumps({'name': 'image-1', 'foo': 'bar', 'disk_format': 'aki', 'container_format': 'aki', 'x_owner_foo': 'o_s_bar'}) response = requests.post(path, headers=headers, data=data) self.assertEqual(403, response.status_code) ## Create an image for role member without 'foo' path = self._url('/v2/images') headers = self._headers({'content-type': 'application/json', 'X-Roles': 'member'}) data = jsonutils.dumps({'name': 'image-1', 'disk_format': 'aki', 'container_format': 'aki', 'x_owner_foo': 'o_s_bar'}) response = requests.post(path, headers=headers, data=data) self.assertEqual(201, response.status_code) # Returned image entity should have 'x_owner_foo' image = jsonutils.loads(response.text) image_id = image['id'] expected_image = { 'status': 'queued', 'name': 'image-1', 'tags': [], 'visibility': 'private', 'self': '/v2/images/%s' % image_id, 'protected': False, 'file': '/v2/images/%s/file' % image_id, 'min_disk': 0, 'x_owner_foo': 'o_s_bar', 'min_ram': 0, 'schema': '/v2/schemas/image', } for key, value in expected_image.items(): self.assertEqual(image[key], value, key) # Create an image for role spl_role with extra props path = self._url('/v2/images') headers = self._headers({'content-type': 'application/json', 'X-Roles': 'spl_role'}) data = jsonutils.dumps({'name': 'image-1', 'disk_format': 'aki', 'container_format': 'aki', 'spl_create_prop': 'create_bar', 'spl_create_prop_policy': 'create_policy_bar', 'spl_read_prop': 'read_bar', 'spl_update_prop': 'update_bar', 'spl_delete_prop': 'delete_bar'}) response = requests.post(path, headers=headers, data=data) self.assertEqual(201, response.status_code) image = jsonutils.loads(response.text) image_id = image['id'] # Attempt to replace, add and remove properties which are forbidden path = self._url('/v2/images/%s' % image_id) media_type = 'application/openstack-images-v2.1-json-patch' headers = self._headers({'content-type': media_type, 'X-Roles': 'spl_role'}) data = jsonutils.dumps([ {'op': 'replace', 'path': '/spl_read_prop', 'value': 'r'}, {'op': 'replace', 'path': '/spl_update_prop', 'value': 'u'}, ]) response = requests.patch(path, headers=headers, data=data) self.assertEqual(403, response.status_code, response.text) # Attempt to replace, add and remove properties which are forbidden path = self._url('/v2/images/%s' % image_id) media_type = 'application/openstack-images-v2.1-json-patch' headers = self._headers({'content-type': media_type, 'X-Roles': 'spl_role'}) data = jsonutils.dumps([ {'op': 'add', 'path': '/spl_new_prop', 'value': 'new'}, {'op': 'remove', 'path': '/spl_create_prop'}, {'op': 'remove', 'path': '/spl_delete_prop'}, ]) response = requests.patch(path, headers=headers, data=data) self.assertEqual(403, response.status_code, response.text) # Attempt to replace, add and remove properties path = self._url('/v2/images/%s' % image_id) media_type = 'application/openstack-images-v2.1-json-patch' headers = self._headers({'content-type': media_type, 'X-Roles': 'spl_role'}) data = jsonutils.dumps([ {'op': 'replace', 'path': '/spl_update_prop', 'value': 'u'}, {'op': 'remove', 'path': '/spl_delete_prop'}, ]) response = requests.patch(path, headers=headers, data=data) self.assertEqual(200, response.status_code, response.text) # Returned image entity should reflect the changes image = jsonutils.loads(response.text) # 'spl_update_prop' has update permission for spl_role # hence the value has changed self.assertEqual('u', image['spl_update_prop']) # 'spl_delete_prop' has delete permission for spl_role # hence the property has been deleted self.assertTrue('spl_delete_prop' not in image.keys()) # Image Deletion should work path = self._url('/v2/images/%s' % image_id) response = requests.delete(path, headers=self._headers()) self.assertEqual(204, response.status_code) # This image should be no longer be directly accessible path = self._url('/v2/images/%s' % image_id) response = requests.get(path, headers=self._headers()) self.assertEqual(404, response.status_code) self.stop_servers() def test_property_protections_with_policies(self): # Enable property protection self.api_server.property_protection_file = self.property_file_policies self.api_server.property_protection_rule_format = 'policies' self.start_servers(**self.__dict__.copy()) # Image list should be empty path = self._url('/v2/images') response = requests.get(path, headers=self._headers()) self.assertEqual(200, response.status_code) images = jsonutils.loads(response.text)['images'] self.assertEqual(0, len(images)) ## Create an image for role member with extra props # Raises 403 since user is not allowed to set 'foo' path = self._url('/v2/images') headers = self._headers({'content-type': 'application/json', 'X-Roles': 'member'}) data = jsonutils.dumps({'name': 'image-1', 'foo': 'bar', 'disk_format': 'aki', 'container_format': 'aki', 'x_owner_foo': 'o_s_bar'}) response = requests.post(path, headers=headers, data=data) self.assertEqual(403, response.status_code) ## Create an image for role member without 'foo' path = self._url('/v2/images') headers = self._headers({'content-type': 'application/json', 'X-Roles': 'member'}) data = jsonutils.dumps({'name': 'image-1', 'disk_format': 'aki', 'container_format': 'aki'}) response = requests.post(path, headers=headers, data=data) self.assertEqual(201, response.status_code) # Returned image entity image = jsonutils.loads(response.text) image_id = image['id'] expected_image = { 'status': 'queued', 'name': 'image-1', 'tags': [], 'visibility': 'private', 'self': '/v2/images/%s' % image_id, 'protected': False, 'file': '/v2/images/%s/file' % image_id, 'min_disk': 0, 'min_ram': 0, 'schema': '/v2/schemas/image', } for key, value in expected_image.items(): self.assertEqual(image[key], value, key) # Create an image for role spl_role with extra props path = self._url('/v2/images') headers = self._headers({'content-type': 'application/json', 'X-Roles': 'spl_role, admin'}) data = jsonutils.dumps({'name': 'image-1', 'disk_format': 'aki', 'container_format': 'aki', 'spl_creator_policy': 'creator_bar', 'spl_default_policy': 'default_bar'}) response = requests.post(path, headers=headers, data=data) self.assertEqual(201, response.status_code) image = jsonutils.loads(response.text) image_id = image['id'] self.assertEqual('creator_bar', image['spl_creator_policy']) self.assertEqual('default_bar', image['spl_default_policy']) # Attempt to replace a property which is permitted path = self._url('/v2/images/%s' % image_id) media_type = 'application/openstack-images-v2.1-json-patch' headers = self._headers({'content-type': media_type, 'X-Roles': 'admin'}) data = jsonutils.dumps([ {'op': 'replace', 'path': '/spl_creator_policy', 'value': 'r'}, ]) response = requests.patch(path, headers=headers, data=data) self.assertEqual(200, response.status_code, response.text) # Returned image entity should reflect the changes image = jsonutils.loads(response.text) # 'spl_creator_policy' has update permission for admin # hence the value has changed self.assertEqual('r', image['spl_creator_policy']) # Attempt to replace a property which is forbidden path = self._url('/v2/images/%s' % image_id) media_type = 'application/openstack-images-v2.1-json-patch' headers = self._headers({'content-type': media_type, 'X-Roles': 'spl_role'}) data = jsonutils.dumps([ {'op': 'replace', 'path': '/spl_creator_policy', 'value': 'z'}, ]) response = requests.patch(path, headers=headers, data=data) self.assertEqual(403, response.status_code, response.text) # Attempt to read properties path = self._url('/v2/images/%s' % image_id) headers = self._headers({'content-type': media_type, 'X-Roles': 'random_role'}) response = requests.get(path, headers=headers) self.assertEqual(200, response.status_code) image = jsonutils.loads(response.text) # 'random_role' is allowed read 'spl_default_policy'. self.assertEqual(image['spl_default_policy'], 'default_bar') # 'random_role' is forbidden to read 'spl_creator_policy'. self.assertFalse('spl_creator_policy' in image) # Attempt to add and remove properties which are permitted path = self._url('/v2/images/%s' % image_id) media_type = 'application/openstack-images-v2.1-json-patch' headers = self._headers({'content-type': media_type, 'X-Roles': 'admin'}) data = jsonutils.dumps([ {'op': 'remove', 'path': '/spl_creator_policy'}, ]) response = requests.patch(path, headers=headers, data=data) self.assertEqual(200, response.status_code, response.text) # Returned image entity should reflect the changes image = jsonutils.loads(response.text) # 'spl_creator_policy' has delete permission for admin # hence the value has been deleted self.assertFalse('spl_creator_policy' in image) # Attempt to read a property that is permitted path = self._url('/v2/images/%s' % image_id) headers = self._headers({'content-type': media_type, 'X-Roles': 'random_role'}) response = requests.get(path, headers=headers) self.assertEqual(200, response.status_code) # Returned image entity should reflect the changes image = jsonutils.loads(response.text) self.assertEqual(image['spl_default_policy'], 'default_bar') # Image Deletion should work path = self._url('/v2/images/%s' % image_id) response = requests.delete(path, headers=self._headers()) self.assertEqual(204, response.status_code) # This image should be no longer be directly accessible path = self._url('/v2/images/%s' % image_id) response = requests.get(path, headers=self._headers()) self.assertEqual(404, response.status_code) self.stop_servers() def test_property_protections_special_chars_roles(self): # Enable property protection self.api_server.property_protection_file = self.property_file_roles self.start_servers(**self.__dict__.copy()) # Verify both admin and unknown role can create properties marked with # '@' path = self._url('/v2/images') headers = self._headers({'content-type': 'application/json', 'X-Roles': 'admin'}) data = jsonutils.dumps({ 'name': 'image-1', 'disk_format': 'aki', 'container_format': 'aki', 'x_all_permitted_admin': '1' }) response = requests.post(path, headers=headers, data=data) self.assertEqual(201, response.status_code) image = jsonutils.loads(response.text) image_id = image['id'] expected_image = { 'status': 'queued', 'name': 'image-1', 'tags': [], 'visibility': 'private', 'self': '/v2/images/%s' % image_id, 'protected': False, 'file': '/v2/images/%s/file' % image_id, 'min_disk': 0, 'x_all_permitted_admin': '1', 'min_ram': 0, 'schema': '/v2/schemas/image', } for key, value in expected_image.items(): self.assertEqual(image[key], value, key) path = self._url('/v2/images') headers = self._headers({'content-type': 'application/json', 'X-Roles': 'joe_soap'}) data = jsonutils.dumps({ 'name': 'image-1', 'disk_format': 'aki', 'container_format': 'aki', 'x_all_permitted_joe_soap': '1' }) response = requests.post(path, headers=headers, data=data) self.assertEqual(201, response.status_code) image = jsonutils.loads(response.text) image_id = image['id'] expected_image = { 'status': 'queued', 'name': 'image-1', 'tags': [], 'visibility': 'private', 'self': '/v2/images/%s' % image_id, 'protected': False, 'file': '/v2/images/%s/file' % image_id, 'min_disk': 0, 'x_all_permitted_joe_soap': '1', 'min_ram': 0, 'schema': '/v2/schemas/image', } for key, value in expected_image.items(): self.assertEqual(image[key], value, key) # Verify both admin and unknown role can read properties marked with # '@' headers = self._headers({'content-type': 'application/json', 'X-Roles': 'admin'}) path = self._url('/v2/images/%s' % image_id) response = requests.get(path, headers=self._headers()) self.assertEqual(200, response.status_code) image = jsonutils.loads(response.text) self.assertEqual('1', image['x_all_permitted_joe_soap']) headers = self._headers({'content-type': 'application/json', 'X-Roles': 'joe_soap'}) path = self._url('/v2/images/%s' % image_id) response = requests.get(path, headers=self._headers()) self.assertEqual(200, response.status_code) image = jsonutils.loads(response.text) self.assertEqual('1', image['x_all_permitted_joe_soap']) # Verify both admin and unknown role can update properties marked with # '@' path = self._url('/v2/images/%s' % image_id) media_type = 'application/openstack-images-v2.1-json-patch' headers = self._headers({'content-type': media_type, 'X-Roles': 'admin'}) data = jsonutils.dumps([ {'op': 'replace', 'path': '/x_all_permitted_joe_soap', 'value': '2'} ]) response = requests.patch(path, headers=headers, data=data) self.assertEqual(200, response.status_code, response.text) image = jsonutils.loads(response.text) self.assertEqual('2', image['x_all_permitted_joe_soap']) path = self._url('/v2/images/%s' % image_id) media_type = 'application/openstack-images-v2.1-json-patch' headers = self._headers({'content-type': media_type, 'X-Roles': 'joe_soap'}) data = jsonutils.dumps([ {'op': 'replace', 'path': '/x_all_permitted_joe_soap', 'value': '3'} ]) response = requests.patch(path, headers=headers, data=data) self.assertEqual(200, response.status_code, response.text) image = jsonutils.loads(response.text) self.assertEqual('3', image['x_all_permitted_joe_soap']) # Verify both admin and unknown role can delete properties marked with # '@' path = self._url('/v2/images') headers = self._headers({'content-type': 'application/json', 'X-Roles': 'admin'}) data = jsonutils.dumps({ 'name': 'image-1', 'disk_format': 'aki', 'container_format': 'aki', 'x_all_permitted_a': '1', 'x_all_permitted_b': '2' }) response = requests.post(path, headers=headers, data=data) self.assertEqual(201, response.status_code) image = jsonutils.loads(response.text) image_id = image['id'] path = self._url('/v2/images/%s' % image_id) media_type = 'application/openstack-images-v2.1-json-patch' headers = self._headers({'content-type': media_type, 'X-Roles': 'admin'}) data = jsonutils.dumps([ {'op': 'remove', 'path': '/x_all_permitted_a'} ]) response = requests.patch(path, headers=headers, data=data) self.assertEqual(200, response.status_code, response.text) image = jsonutils.loads(response.text) self.assertNotIn('x_all_permitted_a', image.keys()) path = self._url('/v2/images/%s' % image_id) media_type = 'application/openstack-images-v2.1-json-patch' headers = self._headers({'content-type': media_type, 'X-Roles': 'joe_soap'}) data = jsonutils.dumps([ {'op': 'remove', 'path': '/x_all_permitted_b'} ]) response = requests.patch(path, headers=headers, data=data) self.assertEqual(200, response.status_code, response.text) image = jsonutils.loads(response.text) self.assertNotIn('x_all_permitted_b', image.keys()) # Verify neither admin nor unknown role can create a property protected # with '!' path = self._url('/v2/images') headers = self._headers({'content-type': 'application/json', 'X-Roles': 'admin'}) data = jsonutils.dumps({ 'name': 'image-1', 'disk_format': 'aki', 'container_format': 'aki', 'x_none_permitted_admin': '1' }) response = requests.post(path, headers=headers, data=data) self.assertEqual(403, response.status_code) path = self._url('/v2/images') headers = self._headers({'content-type': 'application/json', 'X-Roles': 'joe_soap'}) data = jsonutils.dumps({ 'name': 'image-1', 'disk_format': 'aki', 'container_format': 'aki', 'x_none_permitted_joe_soap': '1' }) response = requests.post(path, headers=headers, data=data) self.assertEqual(403, response.status_code) # Verify neither admin nor unknown role can read properties marked with # '!' path = self._url('/v2/images') headers = self._headers({'content-type': 'application/json', 'X-Roles': 'admin'}) data = jsonutils.dumps({ 'name': 'image-1', 'disk_format': 'aki', 'container_format': 'aki', 'x_none_read': '1' }) response = requests.post(path, headers=headers, data=data) self.assertEqual(201, response.status_code) image = jsonutils.loads(response.text) image_id = image['id'] self.assertNotIn('x_none_read', image.keys()) headers = self._headers({'content-type': 'application/json', 'X-Roles': 'admin'}) path = self._url('/v2/images/%s' % image_id) response = requests.get(path, headers=self._headers()) self.assertEqual(200, response.status_code) image = jsonutils.loads(response.text) self.assertNotIn('x_none_read', image.keys()) headers = self._headers({'content-type': 'application/json', 'X-Roles': 'joe_soap'}) path = self._url('/v2/images/%s' % image_id) response = requests.get(path, headers=self._headers()) self.assertEqual(200, response.status_code) image = jsonutils.loads(response.text) self.assertNotIn('x_none_read', image.keys()) # Verify neither admin nor unknown role can update properties marked # with '!' path = self._url('/v2/images') headers = self._headers({'content-type': 'application/json', 'X-Roles': 'admin'}) data = jsonutils.dumps({ 'name': 'image-1', 'disk_format': 'aki', 'container_format': 'aki', 'x_none_update': '1' }) response = requests.post(path, headers=headers, data=data) self.assertEqual(201, response.status_code) image = jsonutils.loads(response.text) image_id = image['id'] self.assertEqual('1', image['x_none_update']) path = self._url('/v2/images/%s' % image_id) media_type = 'application/openstack-images-v2.1-json-patch' headers = self._headers({'content-type': media_type, 'X-Roles': 'admin'}) data = jsonutils.dumps([ {'op': 'replace', 'path': '/x_none_update', 'value': '2'} ]) response = requests.patch(path, headers=headers, data=data) self.assertEqual(403, response.status_code, response.text) path = self._url('/v2/images/%s' % image_id) media_type = 'application/openstack-images-v2.1-json-patch' headers = self._headers({'content-type': media_type, 'X-Roles': 'joe_soap'}) data = jsonutils.dumps([ {'op': 'replace', 'path': '/x_none_update', 'value': '3'} ]) response = requests.patch(path, headers=headers, data=data) self.assertEqual(409, response.status_code, response.text) # Verify neither admin nor unknown role can delete properties marked # with '!' path = self._url('/v2/images') headers = self._headers({'content-type': 'application/json', 'X-Roles': 'admin'}) data = jsonutils.dumps({ 'name': 'image-1', 'disk_format': 'aki', 'container_format': 'aki', 'x_none_delete': '1', }) response = requests.post(path, headers=headers, data=data) self.assertEqual(201, response.status_code) image = jsonutils.loads(response.text) image_id = image['id'] path = self._url('/v2/images/%s' % image_id) media_type = 'application/openstack-images-v2.1-json-patch' headers = self._headers({'content-type': media_type, 'X-Roles': 'admin'}) data = jsonutils.dumps([ {'op': 'remove', 'path': '/x_none_delete'} ]) response = requests.patch(path, headers=headers, data=data) self.assertEqual(403, response.status_code, response.text) path = self._url('/v2/images/%s' % image_id) media_type = 'application/openstack-images-v2.1-json-patch' headers = self._headers({'content-type': media_type, 'X-Roles': 'joe_soap'}) data = jsonutils.dumps([ {'op': 'remove', 'path': '/x_none_delete'} ]) response = requests.patch(path, headers=headers, data=data) self.assertEqual(409, response.status_code, response.text) self.stop_servers() def test_property_protections_special_chars_policies(self): # Enable property protection self.api_server.property_protection_file = self.property_file_policies self.api_server.property_protection_rule_format = 'policies' self.start_servers(**self.__dict__.copy()) # Verify both admin and unknown role can create properties marked with # '@' path = self._url('/v2/images') headers = self._headers({'content-type': 'application/json', 'X-Roles': 'admin'}) data = jsonutils.dumps({ 'name': 'image-1', 'disk_format': 'aki', 'container_format': 'aki', 'x_all_permitted_admin': '1' }) response = requests.post(path, headers=headers, data=data) self.assertEqual(201, response.status_code) image = jsonutils.loads(response.text) image_id = image['id'] expected_image = { 'status': 'queued', 'name': 'image-1', 'tags': [], 'visibility': 'private', 'self': '/v2/images/%s' % image_id, 'protected': False, 'file': '/v2/images/%s/file' % image_id, 'min_disk': 0, 'x_all_permitted_admin': '1', 'min_ram': 0, 'schema': '/v2/schemas/image', } for key, value in expected_image.items(): self.assertEqual(image[key], value, key) path = self._url('/v2/images') headers = self._headers({'content-type': 'application/json', 'X-Roles': 'joe_soap'}) data = jsonutils.dumps({ 'name': 'image-1', 'disk_format': 'aki', 'container_format': 'aki', 'x_all_permitted_joe_soap': '1' }) response = requests.post(path, headers=headers, data=data) self.assertEqual(201, response.status_code) image = jsonutils.loads(response.text) image_id = image['id'] expected_image = { 'status': 'queued', 'name': 'image-1', 'tags': [], 'visibility': 'private', 'self': '/v2/images/%s' % image_id, 'protected': False, 'file': '/v2/images/%s/file' % image_id, 'min_disk': 0, 'x_all_permitted_joe_soap': '1', 'min_ram': 0, 'schema': '/v2/schemas/image', } for key, value in expected_image.items(): self.assertEqual(image[key], value, key) # Verify both admin and unknown role can read properties marked with # '@' headers = self._headers({'content-type': 'application/json', 'X-Roles': 'admin'}) path = self._url('/v2/images/%s' % image_id) response = requests.get(path, headers=self._headers()) self.assertEqual(200, response.status_code) image = jsonutils.loads(response.text) self.assertEqual('1', image['x_all_permitted_joe_soap']) headers = self._headers({'content-type': 'application/json', 'X-Roles': 'joe_soap'}) path = self._url('/v2/images/%s' % image_id) response = requests.get(path, headers=self._headers()) self.assertEqual(200, response.status_code) image = jsonutils.loads(response.text) self.assertEqual('1', image['x_all_permitted_joe_soap']) # Verify both admin and unknown role can update properties marked with # '@' path = self._url('/v2/images/%s' % image_id) media_type = 'application/openstack-images-v2.1-json-patch' headers = self._headers({'content-type': media_type, 'X-Roles': 'admin'}) data = jsonutils.dumps([ {'op': 'replace', 'path': '/x_all_permitted_joe_soap', 'value': '2'} ]) response = requests.patch(path, headers=headers, data=data) self.assertEqual(200, response.status_code, response.text) image = jsonutils.loads(response.text) self.assertEqual('2', image['x_all_permitted_joe_soap']) path = self._url('/v2/images/%s' % image_id) media_type = 'application/openstack-images-v2.1-json-patch' headers = self._headers({'content-type': media_type, 'X-Roles': 'joe_soap'}) data = jsonutils.dumps([ {'op': 'replace', 'path': '/x_all_permitted_joe_soap', 'value': '3'} ]) response = requests.patch(path, headers=headers, data=data) self.assertEqual(200, response.status_code, response.text) image = jsonutils.loads(response.text) self.assertEqual('3', image['x_all_permitted_joe_soap']) # Verify both admin and unknown role can delete properties marked with # '@' path = self._url('/v2/images') headers = self._headers({'content-type': 'application/json', 'X-Roles': 'admin'}) data = jsonutils.dumps({ 'name': 'image-1', 'disk_format': 'aki', 'container_format': 'aki', 'x_all_permitted_a': '1', 'x_all_permitted_b': '2' }) response = requests.post(path, headers=headers, data=data) self.assertEqual(201, response.status_code) image = jsonutils.loads(response.text) image_id = image['id'] path = self._url('/v2/images/%s' % image_id) media_type = 'application/openstack-images-v2.1-json-patch' headers = self._headers({'content-type': media_type, 'X-Roles': 'admin'}) data = jsonutils.dumps([ {'op': 'remove', 'path': '/x_all_permitted_a'} ]) response = requests.patch(path, headers=headers, data=data) self.assertEqual(200, response.status_code, response.text) image = jsonutils.loads(response.text) self.assertNotIn('x_all_permitted_a', image.keys()) path = self._url('/v2/images/%s' % image_id) media_type = 'application/openstack-images-v2.1-json-patch' headers = self._headers({'content-type': media_type, 'X-Roles': 'joe_soap'}) data = jsonutils.dumps([ {'op': 'remove', 'path': '/x_all_permitted_b'} ]) response = requests.patch(path, headers=headers, data=data) self.assertEqual(200, response.status_code, response.text) image = jsonutils.loads(response.text) self.assertNotIn('x_all_permitted_b', image.keys()) # Verify neither admin nor unknown role can create a property protected # with '!' path = self._url('/v2/images') headers = self._headers({'content-type': 'application/json', 'X-Roles': 'admin'}) data = jsonutils.dumps({ 'name': 'image-1', 'disk_format': 'aki', 'container_format': 'aki', 'x_none_permitted_admin': '1' }) response = requests.post(path, headers=headers, data=data) self.assertEqual(403, response.status_code) path = self._url('/v2/images') headers = self._headers({'content-type': 'application/json', 'X-Roles': 'joe_soap'}) data = jsonutils.dumps({ 'name': 'image-1', 'disk_format': 'aki', 'container_format': 'aki', 'x_none_permitted_joe_soap': '1' }) response = requests.post(path, headers=headers, data=data) self.assertEqual(403, response.status_code) # Verify neither admin nor unknown role can read properties marked with # '!' path = self._url('/v2/images') headers = self._headers({'content-type': 'application/json', 'X-Roles': 'admin'}) data = jsonutils.dumps({ 'name': 'image-1', 'disk_format': 'aki', 'container_format': 'aki', 'x_none_read': '1' }) response = requests.post(path, headers=headers, data=data) self.assertEqual(201, response.status_code) image = jsonutils.loads(response.text) image_id = image['id'] self.assertNotIn('x_none_read', image.keys()) headers = self._headers({'content-type': 'application/json', 'X-Roles': 'admin'}) path = self._url('/v2/images/%s' % image_id) response = requests.get(path, headers=self._headers()) self.assertEqual(200, response.status_code) image = jsonutils.loads(response.text) self.assertNotIn('x_none_read', image.keys()) headers = self._headers({'content-type': 'application/json', 'X-Roles': 'joe_soap'}) path = self._url('/v2/images/%s' % image_id) response = requests.get(path, headers=self._headers()) self.assertEqual(200, response.status_code) image = jsonutils.loads(response.text) self.assertNotIn('x_none_read', image.keys()) # Verify neither admin nor unknown role can update properties marked # with '!' path = self._url('/v2/images') headers = self._headers({'content-type': 'application/json', 'X-Roles': 'admin'}) data = jsonutils.dumps({ 'name': 'image-1', 'disk_format': 'aki', 'container_format': 'aki', 'x_none_update': '1' }) response = requests.post(path, headers=headers, data=data) self.assertEqual(201, response.status_code) image = jsonutils.loads(response.text) image_id = image['id'] self.assertEqual('1', image['x_none_update']) path = self._url('/v2/images/%s' % image_id) media_type = 'application/openstack-images-v2.1-json-patch' headers = self._headers({'content-type': media_type, 'X-Roles': 'admin'}) data = jsonutils.dumps([ {'op': 'replace', 'path': '/x_none_update', 'value': '2'} ]) response = requests.patch(path, headers=headers, data=data) self.assertEqual(403, response.status_code, response.text) path = self._url('/v2/images/%s' % image_id) media_type = 'application/openstack-images-v2.1-json-patch' headers = self._headers({'content-type': media_type, 'X-Roles': 'joe_soap'}) data = jsonutils.dumps([ {'op': 'replace', 'path': '/x_none_update', 'value': '3'} ]) response = requests.patch(path, headers=headers, data=data) self.assertEqual(409, response.status_code, response.text) # Verify neither admin nor unknown role can delete properties marked # with '!' path = self._url('/v2/images') headers = self._headers({'content-type': 'application/json', 'X-Roles': 'admin'}) data = jsonutils.dumps({ 'name': 'image-1', 'disk_format': 'aki', 'container_format': 'aki', 'x_none_delete': '1', }) response = requests.post(path, headers=headers, data=data) self.assertEqual(201, response.status_code) image = jsonutils.loads(response.text) image_id = image['id'] path = self._url('/v2/images/%s' % image_id) media_type = 'application/openstack-images-v2.1-json-patch' headers = self._headers({'content-type': media_type, 'X-Roles': 'admin'}) data = jsonutils.dumps([ {'op': 'remove', 'path': '/x_none_delete'} ]) response = requests.patch(path, headers=headers, data=data) self.assertEqual(403, response.status_code, response.text) path = self._url('/v2/images/%s' % image_id) media_type = 'application/openstack-images-v2.1-json-patch' headers = self._headers({'content-type': media_type, 'X-Roles': 'joe_soap'}) data = jsonutils.dumps([ {'op': 'remove', 'path': '/x_none_delete'} ]) response = requests.patch(path, headers=headers, data=data) self.assertEqual(409, response.status_code, response.text) self.stop_servers() def test_tag_lifecycle(self): # Create an image with a tag - duplicate should be ignored path = self._url('/v2/images') headers = self._headers({'Content-Type': 'application/json'}) data = jsonutils.dumps({'name': 'image-1', 'tags': ['sniff', 'sniff']}) response = requests.post(path, headers=headers, data=data) self.assertEqual(201, response.status_code) image_id = jsonutils.loads(response.text)['id'] # Image should show a list with a single tag path = self._url('/v2/images/%s' % image_id) response = requests.get(path, headers=self._headers()) self.assertEqual(200, response.status_code) tags = jsonutils.loads(response.text)['tags'] self.assertEqual(['sniff'], tags) # Delete all tags for tag in tags: path = self._url('/v2/images/%s/tags/%s' % (image_id, tag)) response = requests.delete(path, headers=self._headers()) self.assertEqual(204, response.status_code) # Update image with too many tags via PUT # Configured limit is 10 tags for i in range(10): path = self._url('/v2/images/%s/tags/foo%i' % (image_id, i)) response = requests.put(path, headers=self._headers()) self.assertEqual(204, response.status_code) # 11th tag should fail path = self._url('/v2/images/%s/tags/fail_me' % image_id) response = requests.put(path, headers=self._headers()) self.assertEqual(413, response.status_code) # Make sure the 11th tag was not added path = self._url('/v2/images/%s' % image_id) response = requests.get(path, headers=self._headers()) self.assertEqual(200, response.status_code) tags = jsonutils.loads(response.text)['tags'] self.assertEqual(10, len(tags)) # Update image tags via PATCH path = self._url('/v2/images/%s' % image_id) media_type = 'application/openstack-images-v2.1-json-patch' headers = self._headers({'content-type': media_type}) doc = [ { 'op': 'replace', 'path': '/tags', 'value': ['foo'], }, ] data = jsonutils.dumps(doc) response = requests.patch(path, headers=headers, data=data) self.assertEqual(200, response.status_code) # Update image with too many tags via PATCH # Configured limit is 10 tags path = self._url('/v2/images/%s' % image_id) media_type = 'application/openstack-images-v2.1-json-patch' headers = self._headers({'content-type': media_type}) tags = ['foo%d' % i for i in range(11)] doc = [ { 'op': 'replace', 'path': '/tags', 'value': tags, }, ] data = jsonutils.dumps(doc) response = requests.patch(path, headers=headers, data=data) self.assertEqual(413, response.status_code) # Tags should not have changed since request was over limit path = self._url('/v2/images/%s' % image_id) response = requests.get(path, headers=self._headers()) self.assertEqual(200, response.status_code) tags = jsonutils.loads(response.text)['tags'] self.assertEqual(['foo'], tags) # Update image with duplicate tag - it should be ignored path = self._url('/v2/images/%s' % image_id) media_type = 'application/openstack-images-v2.1-json-patch' headers = self._headers({'content-type': media_type}) doc = [ { 'op': 'replace', 'path': '/tags', 'value': ['sniff', 'snozz', 'snozz'], }, ] data = jsonutils.dumps(doc) response = requests.patch(path, headers=headers, data=data) self.assertEqual(200, response.status_code) tags = jsonutils.loads(response.text)['tags'] self.assertEqual(['snozz', 'sniff'], tags) # Image should show the appropriate tags path = self._url('/v2/images/%s' % image_id) response = requests.get(path, headers=self._headers()) self.assertEqual(200, response.status_code) tags = jsonutils.loads(response.text)['tags'] self.assertEqual(['snozz', 'sniff'], tags) # Attempt to tag the image with a duplicate should be ignored path = self._url('/v2/images/%s/tags/snozz' % image_id) response = requests.put(path, headers=self._headers()) self.assertEqual(204, response.status_code) # Create another more complex tag path = self._url('/v2/images/%s/tags/gabe%%40example.com' % image_id) response = requests.put(path, headers=self._headers()) self.assertEqual(204, response.status_code) # Double-check that the tags container on the image is populated path = self._url('/v2/images/%s' % image_id) response = requests.get(path, headers=self._headers()) self.assertEqual(200, response.status_code) tags = jsonutils.loads(response.text)['tags'] self.assertEqual(['gabe@example.com', 'snozz', 'sniff'], tags) # Query images by single tag path = self._url('/v2/images?tag=sniff') response = requests.get(path, headers=self._headers()) self.assertEqual(200, response.status_code) images = jsonutils.loads(response.text)['images'] self.assertEqual(1, len(images)) self.assertEqual('image-1', images[0]['name']) # Query images by multiple tags path = self._url('/v2/images?tag=sniff&tag=snozz') response = requests.get(path, headers=self._headers()) self.assertEqual(200, response.status_code) images = jsonutils.loads(response.text)['images'] self.assertEqual(1, len(images)) self.assertEqual('image-1', images[0]['name']) # Query images by tag and other attributes path = self._url('/v2/images?tag=sniff&status=queued') response = requests.get(path, headers=self._headers()) self.assertEqual(200, response.status_code) images = jsonutils.loads(response.text)['images'] self.assertEqual(1, len(images)) self.assertEqual('image-1', images[0]['name']) # Query images by tag and a nonexistent tag path = self._url('/v2/images?tag=sniff&tag=fake') response = requests.get(path, headers=self._headers()) self.assertEqual(200, response.status_code) images = jsonutils.loads(response.text)['images'] self.assertEqual(0, len(images)) # The tag should be deletable path = self._url('/v2/images/%s/tags/gabe%%40example.com' % image_id) response = requests.delete(path, headers=self._headers()) self.assertEqual(204, response.status_code) # List of tags should reflect the deletion path = self._url('/v2/images/%s' % image_id) response = requests.get(path, headers=self._headers()) self.assertEqual(200, response.status_code) tags = jsonutils.loads(response.text)['tags'] self.assertEqual(['snozz', 'sniff'], tags) # Deleting the same tag should return a 404 path = self._url('/v2/images/%s/tags/gabe%%40example.com' % image_id) response = requests.delete(path, headers=self._headers()) self.assertEqual(404, response.status_code) # The tags won't be able to to query the images after deleting path = self._url('/v2/images?tag=gabe%%40example.com') response = requests.get(path, headers=self._headers()) self.assertEqual(200, response.status_code) images = jsonutils.loads(response.text)['images'] self.assertEqual(0, len(images)) self.stop_servers() def test_images_container(self): # Image list should be empty and no next link should be present path = self._url('/v2/images') response = requests.get(path, headers=self._headers()) self.assertEqual(200, response.status_code) images = jsonutils.loads(response.text)['images'] first = jsonutils.loads(response.text)['first'] self.assertEqual(0, len(images)) self.assertTrue('next' not in jsonutils.loads(response.text)) self.assertEqual('/v2/images', first) # Create 7 images images = [] fixtures = [ {'name': 'image-3', 'type': 'kernel', 'ping': 'pong'}, {'name': 'image-4', 'type': 'kernel', 'ping': 'pong'}, {'name': 'image-1', 'type': 'kernel', 'ping': 'pong'}, {'name': 'image-3', 'type': 'ramdisk', 'ping': 'pong'}, {'name': 'image-2', 'type': 'kernel', 'ping': 'ding'}, {'name': 'image-3', 'type': 'kernel', 'ping': 'pong'}, {'name': 'image-2', 'type': 'kernel', 'ping': 'pong'}, ] path = self._url('/v2/images') headers = self._headers({'content-type': 'application/json'}) for fixture in fixtures: data = jsonutils.dumps(fixture) response = requests.post(path, headers=headers, data=data) self.assertEqual(201, response.status_code) images.append(jsonutils.loads(response.text)) # Image list should contain 7 images path = self._url('/v2/images') response = requests.get(path, headers=self._headers()) self.assertEqual(200, response.status_code) body = jsonutils.loads(response.text) self.assertEqual(7, len(body['images'])) self.assertEqual('/v2/images', body['first']) self.assertFalse('next' in jsonutils.loads(response.text)) # Begin pagination after the first image template_url = ('/v2/images?limit=2&sort_dir=asc&sort_key=name' '&marker=%s&type=kernel&ping=pong') path = self._url(template_url % images[2]['id']) response = requests.get(path, headers=self._headers()) self.assertEqual(200, response.status_code) body = jsonutils.loads(response.text) self.assertEqual(2, len(body['images'])) response_ids = [image['id'] for image in body['images']] self.assertEqual([images[6]['id'], images[0]['id']], response_ids) # Continue pagination using next link from previous request path = self._url(body['next']) response = requests.get(path, headers=self._headers()) self.assertEqual(200, response.status_code) body = jsonutils.loads(response.text) self.assertEqual(2, len(body['images'])) response_ids = [image['id'] for image in body['images']] self.assertEqual([images[5]['id'], images[1]['id']], response_ids) # Continue pagination - expect no results path = self._url(body['next']) response = requests.get(path, headers=self._headers()) self.assertEqual(200, response.status_code) body = jsonutils.loads(response.text) self.assertEqual(0, len(body['images'])) # Delete first image path = self._url('/v2/images/%s' % images[0]['id']) response = requests.delete(path, headers=self._headers()) self.assertEqual(204, response.status_code) # Ensure bad request for using a deleted image as marker path = self._url('/v2/images?marker=%s' % images[0]['id']) response = requests.get(path, headers=self._headers()) self.assertEqual(400, response.status_code) self.stop_servers() def test_image_visibility_to_different_users(self): self.cleanup() self.api_server.deployment_flavor = 'fakeauth' self.registry_server.deployment_flavor = 'fakeauth' self.start_servers(**self.__dict__.copy()) owners = ['admin', 'tenant1', 'tenant2', 'none'] visibilities = ['public', 'private'] for owner in owners: for visibility in visibilities: path = self._url('/v2/images') headers = self._headers({ 'content-type': 'application/json', 'X-Auth-Token': 'createuser:%s:admin' % owner, }) data = jsonutils.dumps({ 'name': '%s-%s' % (owner, visibility), 'visibility': visibility, }) response = requests.post(path, headers=headers, data=data) self.assertEqual(201, response.status_code) def list_images(tenant, role='', visibility=None): auth_token = 'user:%s:%s' % (tenant, role) headers = {'X-Auth-Token': auth_token} path = self._url('/v2/images') if visibility is not None: path += '?visibility=%s' % visibility response = requests.get(path, headers=headers) self.assertEqual(response.status_code, 200) return jsonutils.loads(response.text)['images'] # 1. Known user sees public and their own images images = list_images('tenant1') self.assertEqual(len(images), 5) for image in images: self.assertTrue(image['visibility'] == 'public' or 'tenant1' in image['name']) # 2. Known user, visibility=public, sees all public images images = list_images('tenant1', visibility='public') self.assertEqual(len(images), 4) for image in images: self.assertEqual(image['visibility'], 'public') # 3. Known user, visibility=private, sees only their private image images = list_images('tenant1', visibility='private') self.assertEqual(len(images), 1) image = images[0] self.assertEqual(image['visibility'], 'private') self.assertTrue('tenant1' in image['name']) # 4. Unknown user sees only public images images = list_images('none') self.assertEqual(len(images), 4) for image in images: self.assertEqual(image['visibility'], 'public') # 5. Unknown user, visibility=public, sees only public images images = list_images('none', visibility='public') self.assertEqual(len(images), 4) for image in images: self.assertEqual(image['visibility'], 'public') # 6. Unknown user, visibility=private, sees no images images = list_images('none', visibility='private') self.assertEqual(len(images), 0) # 7. Unknown admin sees all images images = list_images('none', role='admin') self.assertEqual(len(images), 8) # 8. Unknown admin, visibility=public, shows only public images images = list_images('none', role='admin', visibility='public') self.assertEqual(len(images), 4) for image in images: self.assertEqual(image['visibility'], 'public') # 9. Unknown admin, visibility=private, sees only private images images = list_images('none', role='admin', visibility='private') self.assertEqual(len(images), 4) for image in images: self.assertEqual(image['visibility'], 'private') # 10. Known admin sees all images images = list_images('admin', role='admin') self.assertEqual(len(images), 8) # 11. Known admin, visibility=public, sees all public images images = list_images('admin', role='admin', visibility='public') self.assertEqual(len(images), 4) for image in images: self.assertEqual(image['visibility'], 'public') # 12. Known admin, visibility=private, sees all private images images = list_images('admin', role='admin', visibility='private') self.assertEqual(len(images), 4) for image in images: self.assertEqual(image['visibility'], 'private') self.stop_servers() def test_update_locations(self): # Create an image path = self._url('/v2/images') headers = self._headers({'content-type': 'application/json'}) data = jsonutils.dumps({'name': 'image-1', 'disk_format': 'aki', 'container_format': 'aki'}) response = requests.post(path, headers=headers, data=data) self.assertEqual(201, response.status_code) # Returned image entity should have a generated id and status image = jsonutils.loads(response.text) image_id = image['id'] self.assertEqual(image['status'], 'queued') self.assertNotIn('size', image) self.assertNotIn('virtual_size', image) file_path = os.path.join(self.test_dir, 'fake_image') with open(file_path, 'w') as fap: fap.write('glance') # Update locations for the queued image path = self._url('/v2/images/%s' % image_id) media_type = 'application/openstack-images-v2.1-json-patch' headers = self._headers({'content-type': media_type}) data = jsonutils.dumps([{'op': 'replace', 'path': '/locations', 'value': [{'url': 'file://' + file_path, 'metadata': {}}]}]) response = requests.patch(path, headers=headers, data=data) self.assertEqual(200, response.status_code, response.text) # The image size should be updated path = self._url('/v2/images/%s' % image_id) response = requests.get(path, headers=headers) self.assertEqual(200, response.status_code) image = jsonutils.loads(response.text) self.assertEqual(image['size'], 6) class TestImageDirectURLVisibility(functional.FunctionalTest): def setUp(self): super(TestImageDirectURLVisibility, self).setUp() self.cleanup() self.api_server.deployment_flavor = 'noauth' def _url(self, path): return 'http://127.0.0.1:%d%s' % (self.api_port, path) def _headers(self, custom_headers=None): base_headers = { 'X-Identity-Status': 'Confirmed', 'X-Auth-Token': '932c5c84-02ac-4fe5-a9ba-620af0e2bb96', 'X-User-Id': 'f9a41d13-0c13-47e9-bee2-ce4e8bfe958e', 'X-Tenant-Id': TENANT1, 'X-Roles': 'member', } base_headers.update(custom_headers or {}) return base_headers def test_v2_not_enabled(self): self.api_server.enable_v2_api = False self.start_servers(**self.__dict__.copy()) path = self._url('/v2/images') response = requests.get(path, headers=self._headers()) self.assertEqual(300, response.status_code) self.stop_servers() def test_v2_enabled(self): self.api_server.enable_v2_api = True self.start_servers(**self.__dict__.copy()) path = self._url('/v2/images') response = requests.get(path, headers=self._headers()) self.assertEqual(200, response.status_code) self.stop_servers() def test_image_direct_url_visible(self): self.api_server.show_image_direct_url = True self.start_servers(**self.__dict__.copy()) # Image list should be empty path = self._url('/v2/images') response = requests.get(path, headers=self._headers()) self.assertEqual(200, response.status_code) images = jsonutils.loads(response.text)['images'] self.assertEqual(0, len(images)) # Create an image path = self._url('/v2/images') headers = self._headers({'content-type': 'application/json'}) data = jsonutils.dumps({'name': 'image-1', 'type': 'kernel', 'foo': 'bar', 'disk_format': 'aki', 'container_format': 'aki', 'visibility': 'public'}) response = requests.post(path, headers=headers, data=data) self.assertEqual(201, response.status_code) # Get the image id image = jsonutils.loads(response.text) image_id = image['id'] # Image direct_url should not be visible before location is set path = self._url('/v2/images/%s' % image_id) headers = self._headers({'Content-Type': 'application/json'}) response = requests.get(path, headers=headers) self.assertEqual(200, response.status_code) image = jsonutils.loads(response.text) self.assertFalse('direct_url' in image) # Upload some image data, setting the image location path = self._url('/v2/images/%s/file' % image_id) headers = self._headers({'Content-Type': 'application/octet-stream'}) response = requests.put(path, headers=headers, data='ZZZZZ') self.assertEqual(204, response.status_code) # Image direct_url should be visible path = self._url('/v2/images/%s' % image_id) headers = self._headers({'Content-Type': 'application/json'}) response = requests.get(path, headers=headers) self.assertEqual(200, response.status_code) image = jsonutils.loads(response.text) self.assertTrue('direct_url' in image) # Image direct_url should be visible to non-owner, non-admin user path = self._url('/v2/images/%s' % image_id) headers = self._headers({'Content-Type': 'application/json', 'X-Tenant-Id': TENANT2}) response = requests.get(path, headers=headers) self.assertEqual(200, response.status_code) image = jsonutils.loads(response.text) self.assertIn('direct_url', image) # Image direct_url should be visible in a list path = self._url('/v2/images') headers = self._headers({'Content-Type': 'application/json'}) response = requests.get(path, headers=headers) self.assertEqual(200, response.status_code) image = jsonutils.loads(response.text)['images'][0] self.assertTrue('direct_url' in image) self.stop_servers() def test_image_multiple_location_url_visible(self): self.api_server.show_multiple_locations = True self.start_servers(**self.__dict__.copy()) # Create an image path = self._url('/v2/images') headers = self._headers({'content-type': 'application/json'}) data = jsonutils.dumps({'name': 'image-1', 'type': 'kernel', 'foo': 'bar', 'disk_format': 'aki', 'container_format': 'aki'}) response = requests.post(path, headers=headers, data=data) self.assertEqual(201, response.status_code) # Get the image id image = jsonutils.loads(response.text) image_id = image['id'] # Image locations should not be visible before location is set path = self._url('/v2/images/%s' % image_id) headers = self._headers({'Content-Type': 'application/json'}) response = requests.get(path, headers=headers) self.assertEqual(200, response.status_code) image = jsonutils.loads(response.text) self.assertTrue('locations' in image) self.assertTrue(image["locations"] == []) # Upload some image data, setting the image location path = self._url('/v2/images/%s/file' % image_id) headers = self._headers({'Content-Type': 'application/octet-stream'}) response = requests.put(path, headers=headers, data='ZZZZZ') self.assertEqual(204, response.status_code) # Image locations should be visible path = self._url('/v2/images/%s' % image_id) headers = self._headers({'Content-Type': 'application/json'}) response = requests.get(path, headers=headers) self.assertEqual(200, response.status_code) image = jsonutils.loads(response.text) self.assertTrue('locations' in image) loc = image['locations'] self.assertTrue(len(loc) > 0) loc = loc[0] self.assertTrue('url' in loc) self.assertTrue('metadata' in loc) self.stop_servers() def test_image_direct_url_not_visible(self): self.api_server.show_image_direct_url = False self.start_servers(**self.__dict__.copy()) # Image list should be empty path = self._url('/v2/images') response = requests.get(path, headers=self._headers()) self.assertEqual(200, response.status_code) images = jsonutils.loads(response.text)['images'] self.assertEqual(0, len(images)) # Create an image path = self._url('/v2/images') headers = self._headers({'content-type': 'application/json'}) data = jsonutils.dumps({'name': 'image-1', 'type': 'kernel', 'foo': 'bar', 'disk_format': 'aki', 'container_format': 'aki'}) response = requests.post(path, headers=headers, data=data) self.assertEqual(201, response.status_code) # Get the image id image = jsonutils.loads(response.text) image_id = image['id'] # Upload some image data, setting the image location path = self._url('/v2/images/%s/file' % image_id) headers = self._headers({'Content-Type': 'application/octet-stream'}) response = requests.put(path, headers=headers, data='ZZZZZ') self.assertEqual(204, response.status_code) # Image direct_url should not be visible path = self._url('/v2/images/%s' % image_id) headers = self._headers({'Content-Type': 'application/json'}) response = requests.get(path, headers=headers) self.assertEqual(200, response.status_code) image = jsonutils.loads(response.text) self.assertFalse('direct_url' in image) # Image direct_url should not be visible in a list path = self._url('/v2/images') headers = self._headers({'Content-Type': 'application/json'}) response = requests.get(path, headers=headers) self.assertEqual(200, response.status_code) image = jsonutils.loads(response.text)['images'][0] self.assertFalse('direct_url' in image) self.stop_servers() class TestImageLocationSelectionStrategy(functional.FunctionalTest): def setUp(self): super(TestImageLocationSelectionStrategy, self).setUp() self.cleanup() self.api_server.deployment_flavor = 'noauth' self.foo_image_file = tempfile.NamedTemporaryFile() self.foo_image_file.write("foo image file") self.foo_image_file.flush() self.addCleanup(self.foo_image_file.close) ret = test_http.http_server("foo_image_id", "foo_image") self.http_server_pid, self.http_port = ret def tearDown(self): if self.http_server_pid is not None: os.kill(self.http_server_pid, signal.SIGKILL) super(TestImageLocationSelectionStrategy, self).tearDown() def _url(self, path): return 'http://127.0.0.1:%d%s' % (self.api_port, path) def _headers(self, custom_headers=None): base_headers = { 'X-Identity-Status': 'Confirmed', 'X-Auth-Token': '932c5c84-02ac-4fe5-a9ba-620af0e2bb96', 'X-User-Id': 'f9a41d13-0c13-47e9-bee2-ce4e8bfe958e', 'X-Tenant-Id': TENANT1, 'X-Roles': 'member', } base_headers.update(custom_headers or {}) return base_headers def test_image_locations_with_order_strategy(self): self.api_server.show_image_direct_url = True self.api_server.show_multiple_locations = True self.image_location_quota = 10 self.api_server.location_strategy = 'location_order' preference = "http, swift, filesystem" self.api_server.store_type_location_strategy_preference = preference self.start_servers(**self.__dict__.copy()) # Create an image path = self._url('/v2/images') headers = self._headers({'content-type': 'application/json'}) data = jsonutils.dumps({'name': 'image-1', 'type': 'kernel', 'foo': 'bar', 'disk_format': 'aki', 'container_format': 'aki'}) response = requests.post(path, headers=headers, data=data) self.assertEqual(201, response.status_code) # Get the image id image = jsonutils.loads(response.text) image_id = image['id'] # Image locations should not be visible before location is set path = self._url('/v2/images/%s' % image_id) headers = self._headers({'Content-Type': 'application/json'}) response = requests.get(path, headers=headers) self.assertEqual(200, response.status_code) image = jsonutils.loads(response.text) self.assertTrue('locations' in image) self.assertTrue(image["locations"] == []) # Update image locations via PATCH path = self._url('/v2/images/%s' % image_id) media_type = 'application/openstack-images-v2.1-json-patch' headers = self._headers({'content-type': media_type}) values = [{'url': 'file://%s' % self.foo_image_file.name, 'metadata': {'idx': '1'}}, {'url': 'http://127.0.0.1:%s/foo_image' % self.http_port, 'metadata': {'idx': '0'}}] doc = [{'op': 'replace', 'path': '/locations', 'value': values}] data = jsonutils.dumps(doc) response = requests.patch(path, headers=headers, data=data) self.assertEqual(200, response.status_code) # Image locations should be visible path = self._url('/v2/images/%s' % image_id) headers = self._headers({'Content-Type': 'application/json'}) response = requests.get(path, headers=headers) self.assertEqual(200, response.status_code) image = jsonutils.loads(response.text) self.assertTrue('locations' in image) self.assertEqual(image['locations'], values) self.assertTrue('direct_url' in image) self.assertEqual(image['direct_url'], values[0]['url']) self.stop_servers() def test_image_locatons_with_store_type_strategy(self): self.api_server.show_image_direct_url = True self.api_server.show_multiple_locations = True self.image_location_quota = 10 self.api_server.location_strategy = 'store_type' preference = "http, swift, filesystem" self.api_server.store_type_location_strategy_preference = preference self.start_servers(**self.__dict__.copy()) # Create an image path = self._url('/v2/images') headers = self._headers({'content-type': 'application/json'}) data = jsonutils.dumps({'name': 'image-1', 'type': 'kernel', 'foo': 'bar', 'disk_format': 'aki', 'container_format': 'aki'}) response = requests.post(path, headers=headers, data=data) self.assertEqual(201, response.status_code) # Get the image id image = jsonutils.loads(response.text) image_id = image['id'] # Image locations should not be visible before location is set path = self._url('/v2/images/%s' % image_id) headers = self._headers({'Content-Type': 'application/json'}) response = requests.get(path, headers=headers) self.assertEqual(200, response.status_code) image = jsonutils.loads(response.text) self.assertTrue('locations' in image) self.assertTrue(image["locations"] == []) # Update image locations via PATCH path = self._url('/v2/images/%s' % image_id) media_type = 'application/openstack-images-v2.1-json-patch' headers = self._headers({'content-type': media_type}) values = [{'url': 'file://%s' % self.foo_image_file.name, 'metadata': {'idx': '1'}}, {'url': 'http://127.0.0.1:%s/foo_image' % self.http_port, 'metadata': {'idx': '0'}}] doc = [{'op': 'replace', 'path': '/locations', 'value': values}] data = jsonutils.dumps(doc) response = requests.patch(path, headers=headers, data=data) self.assertEqual(200, response.status_code) values.sort(key=lambda loc: int(loc['metadata']['idx'])) # Image locations should be visible path = self._url('/v2/images/%s' % image_id) headers = self._headers({'Content-Type': 'application/json'}) response = requests.get(path, headers=headers) self.assertEqual(200, response.status_code) image = jsonutils.loads(response.text) self.assertTrue('locations' in image) self.assertEqual(image['locations'], values) self.assertTrue('direct_url' in image) self.assertEqual(image['direct_url'], values[0]['url']) self.stop_servers() class TestImageMembers(functional.FunctionalTest): def setUp(self): super(TestImageMembers, self).setUp() self.cleanup() self.api_server.deployment_flavor = 'fakeauth' self.registry_server.deployment_flavor = 'fakeauth' self.start_servers(**self.__dict__.copy()) def _url(self, path): return 'http://127.0.0.1:%d%s' % (self.api_port, path) def _headers(self, custom_headers=None): base_headers = { 'X-Identity-Status': 'Confirmed', 'X-Auth-Token': '932c5c84-02ac-4fe5-a9ba-620af0e2bb96', 'X-User-Id': 'f9a41d13-0c13-47e9-bee2-ce4e8bfe958e', 'X-Tenant-Id': TENANT1, 'X-Roles': 'member', } base_headers.update(custom_headers or {}) return base_headers def test_image_member_lifecycle(self): def get_header(tenant, role=''): auth_token = 'user:%s:%s' % (tenant, role) headers = {'X-Auth-Token': auth_token} return headers # Image list should be empty path = self._url('/v2/images') response = requests.get(path, headers=get_header('tenant1')) self.assertEqual(200, response.status_code) images = jsonutils.loads(response.text)['images'] self.assertEqual(0, len(images)) owners = ['tenant1', 'tenant2', 'admin'] visibilities = ['public', 'private'] image_fixture = [] for owner in owners: for visibility in visibilities: path = self._url('/v2/images') headers = self._headers({ 'content-type': 'application/json', 'X-Auth-Token': 'createuser:%s:admin' % owner, }) data = jsonutils.dumps({ 'name': '%s-%s' % (owner, visibility), 'visibility': visibility, }) response = requests.post(path, headers=headers, data=data) self.assertEqual(201, response.status_code) image_fixture.append(jsonutils.loads(response.text)) # Image list should contain 4 images for tenant1 path = self._url('/v2/images') response = requests.get(path, headers=get_header('tenant1')) self.assertEqual(200, response.status_code) images = jsonutils.loads(response.text)['images'] self.assertEqual(4, len(images)) # Image list should contain 3 images for TENANT3 path = self._url('/v2/images') response = requests.get(path, headers=get_header(TENANT3)) self.assertEqual(200, response.status_code) images = jsonutils.loads(response.text)['images'] self.assertEqual(3, len(images)) # Add Image member for tenant1-private image path = self._url('/v2/images/%s/members' % image_fixture[1]['id']) body = jsonutils.dumps({'member': TENANT3}) response = requests.post(path, headers=get_header('tenant1'), data=body) self.assertEqual(200, response.status_code) image_member = jsonutils.loads(response.text) self.assertEqual(image_fixture[1]['id'], image_member['image_id']) self.assertEqual(TENANT3, image_member['member_id']) self.assertTrue('created_at' in image_member) self.assertTrue('updated_at' in image_member) self.assertEqual('pending', image_member['status']) # Image list should contain 3 images for TENANT3 path = self._url('/v2/images') response = requests.get(path, headers=get_header(TENANT3)) self.assertEqual(200, response.status_code) images = jsonutils.loads(response.text)['images'] self.assertEqual(3, len(images)) # Image list should contain 0 shared images for TENANT3 # because default is accepted path = self._url('/v2/images?visibility=shared') response = requests.get(path, headers=get_header(TENANT3)) self.assertEqual(200, response.status_code) images = jsonutils.loads(response.text)['images'] self.assertEqual(0, len(images)) # Image list should contain 4 images for TENANT3 with status pending path = self._url('/v2/images?member_status=pending') response = requests.get(path, headers=get_header(TENANT3)) self.assertEqual(200, response.status_code) images = jsonutils.loads(response.text)['images'] self.assertEqual(4, len(images)) # Image list should contain 4 images for TENANT3 with status all path = self._url('/v2/images?member_status=all') response = requests.get(path, headers=get_header(TENANT3)) self.assertEqual(200, response.status_code) images = jsonutils.loads(response.text)['images'] self.assertEqual(4, len(images)) # Image list should contain 1 image for TENANT3 with status pending # and visibility shared path = self._url('/v2/images?member_status=pending&visibility=shared') response = requests.get(path, headers=get_header(TENANT3)) self.assertEqual(200, response.status_code) images = jsonutils.loads(response.text)['images'] self.assertEqual(1, len(images)) self.assertEqual(images[0]['name'], 'tenant1-private') # Image list should contain 0 image for TENANT3 with status rejected # and visibility shared path = self._url('/v2/images?member_status=rejected&visibility=shared') response = requests.get(path, headers=get_header(TENANT3)) self.assertEqual(200, response.status_code) images = jsonutils.loads(response.text)['images'] self.assertEqual(0, len(images)) # Image list should contain 0 image for TENANT3 with status accepted # and visibility shared path = self._url('/v2/images?member_status=accepted&visibility=shared') response = requests.get(path, headers=get_header(TENANT3)) self.assertEqual(200, response.status_code) images = jsonutils.loads(response.text)['images'] self.assertEqual(0, len(images)) # Image list should contain 0 image for TENANT3 with status accepted # and visibility private path = self._url('/v2/images?visibility=private') response = requests.get(path, headers=get_header(TENANT3)) self.assertEqual(200, response.status_code) images = jsonutils.loads(response.text)['images'] self.assertEqual(0, len(images)) # Image tenant2-private's image members list should contain no members path = self._url('/v2/images/%s/members' % image_fixture[3]['id']) response = requests.get(path, headers=get_header('tenant2')) self.assertEqual(200, response.status_code) body = jsonutils.loads(response.text) self.assertEqual(0, len(body['members'])) # Tenant 1, who is the owner cannot change status of image member path = self._url('/v2/images/%s/members/%s' % (image_fixture[1]['id'], TENANT3)) body = jsonutils.dumps({'status': 'accepted'}) response = requests.put(path, headers=get_header('tenant1'), data=body) self.assertEqual(403, response.status_code) # Tenant 1, who is the owner can get status of its own image member path = self._url('/v2/images/%s/members/%s' % (image_fixture[1]['id'], TENANT3)) response = requests.get(path, headers=get_header('tenant1')) self.assertEqual(200, response.status_code) body = jsonutils.loads(response.text) self.assertEqual(body['status'], 'pending') self.assertEqual(body['image_id'], image_fixture[1]['id']) self.assertEqual(body['member_id'], TENANT3) # Tenant 3, who is the member can get status of its own status path = self._url('/v2/images/%s/members/%s' % (image_fixture[1]['id'], TENANT3)) response = requests.get(path, headers=get_header(TENANT3)) self.assertEqual(200, response.status_code) body = jsonutils.loads(response.text) self.assertEqual(body['status'], 'pending') self.assertEqual(body['image_id'], image_fixture[1]['id']) self.assertEqual(body['member_id'], TENANT3) # Tenant 2, who not the owner cannot get status of image member path = self._url('/v2/images/%s/members/%s' % (image_fixture[1]['id'], TENANT3)) response = requests.get(path, headers=get_header('tenant2')) self.assertEqual(404, response.status_code) # Tenant 3 can change status of image member path = self._url('/v2/images/%s/members/%s' % (image_fixture[1]['id'], TENANT3)) body = jsonutils.dumps({'status': 'accepted'}) response = requests.put(path, headers=get_header(TENANT3), data=body) self.assertEqual(200, response.status_code) image_member = jsonutils.loads(response.text) self.assertEqual(image_fixture[1]['id'], image_member['image_id']) self.assertEqual(TENANT3, image_member['member_id']) self.assertEqual('accepted', image_member['status']) # Image list should contain 4 images for TENANT3 because status is # accepted path = self._url('/v2/images') response = requests.get(path, headers=get_header(TENANT3)) self.assertEqual(200, response.status_code) images = jsonutils.loads(response.text)['images'] self.assertEqual(4, len(images)) # Tenant 3 invalid status change path = self._url('/v2/images/%s/members/%s' % (image_fixture[1]['id'], TENANT3)) body = jsonutils.dumps({'status': 'invalid-status'}) response = requests.put(path, headers=get_header(TENANT3), data=body) self.assertEqual(400, response.status_code) # Owner cannot change status of image path = self._url('/v2/images/%s/members/%s' % (image_fixture[1]['id'], TENANT3)) body = jsonutils.dumps({'status': 'accepted'}) response = requests.put(path, headers=get_header('tenant1'), data=body) self.assertEqual(403, response.status_code) # Add Image member for tenant2-private image path = self._url('/v2/images/%s/members' % image_fixture[3]['id']) body = jsonutils.dumps({'member': TENANT4}) response = requests.post(path, headers=get_header('tenant2'), data=body) self.assertEqual(200, response.status_code) image_member = jsonutils.loads(response.text) self.assertEqual(image_fixture[3]['id'], image_member['image_id']) self.assertEqual(TENANT4, image_member['member_id']) self.assertTrue('created_at' in image_member) self.assertTrue('updated_at' in image_member) # Add Image member to public image path = self._url('/v2/images/%s/members' % image_fixture[0]['id']) body = jsonutils.dumps({'member': TENANT2}) response = requests.post(path, headers=get_header('tenant1'), data=body) self.assertEqual(403, response.status_code) # Image tenant1-private's members list should contain 1 member path = self._url('/v2/images/%s/members' % image_fixture[1]['id']) response = requests.get(path, headers=get_header('tenant1')) self.assertEqual(200, response.status_code) body = jsonutils.loads(response.text) self.assertEqual(1, len(body['members'])) # Admin can see any members path = self._url('/v2/images/%s/members' % image_fixture[1]['id']) response = requests.get(path, headers=get_header('tenant1', 'admin')) self.assertEqual(200, response.status_code) body = jsonutils.loads(response.text) self.assertEqual(1, len(body['members'])) # Image members not found for private image not owned by TENANT 1 path = self._url('/v2/images/%s/members' % image_fixture[3]['id']) response = requests.get(path, headers=get_header('tenant1')) self.assertEqual(404, response.status_code) # Image members forbidden for public image path = self._url('/v2/images/%s/members' % image_fixture[0]['id']) response = requests.get(path, headers=get_header('tenant1')) self.assertEqual(403, response.status_code) # Image Member Cannot delete Image membership path = self._url('/v2/images/%s/members/%s' % (image_fixture[1]['id'], TENANT3)) response = requests.delete(path, headers=get_header(TENANT3)) self.assertEqual(403, response.status_code) # Delete Image member path = self._url('/v2/images/%s/members/%s' % (image_fixture[1]['id'], TENANT3)) response = requests.delete(path, headers=get_header('tenant1')) self.assertEqual(204, response.status_code) # Now the image has only no members path = self._url('/v2/images/%s/members' % image_fixture[1]['id']) response = requests.get(path, headers=get_header('tenant1')) self.assertEqual(200, response.status_code) body = jsonutils.loads(response.text) self.assertEqual(0, len(body['members'])) # Adding 11 image members should fail since configured limit is 10 path = self._url('/v2/images/%s/members' % image_fixture[1]['id']) for i in range(10): body = jsonutils.dumps({'member': str(uuid.uuid4())}) response = requests.post(path, headers=get_header('tenant1'), data=body) self.assertEqual(200, response.status_code) body = jsonutils.dumps({'member': str(uuid.uuid4())}) response = requests.post(path, headers=get_header('tenant1'), data=body) self.assertEqual(413, response.status_code) # Delete Image members not found for public image path = self._url('/v2/images/%s/members/%s' % (image_fixture[0]['id'], TENANT3)) response = requests.get(path, headers=get_header('tenant1')) self.assertEqual(404, response.status_code) self.stop_servers() class TestQuotas(functional.FunctionalTest): def setUp(self): super(TestQuotas, self).setUp() self.cleanup() self.api_server.deployment_flavor = 'noauth' self.user_storage_quota = 100 self.start_servers(**self.__dict__.copy()) def _url(self, path): return 'http://127.0.0.1:%d%s' % (self.api_port, path) def _headers(self, custom_headers=None): base_headers = { 'X-Identity-Status': 'Confirmed', 'X-Auth-Token': '932c5c84-02ac-4fe5-a9ba-620af0e2bb96', 'X-User-Id': 'f9a41d13-0c13-47e9-bee2-ce4e8bfe958e', 'X-Tenant-Id': TENANT1, 'X-Roles': 'member', } base_headers.update(custom_headers or {}) return base_headers def _upload_image_test(self, data_src, expected_status): # Image list should be empty path = self._url('/v2/images') response = requests.get(path, headers=self._headers()) self.assertEqual(200, response.status_code) images = jsonutils.loads(response.text)['images'] self.assertEqual(0, len(images)) # Create an image (with a deployer-defined property) path = self._url('/v2/images') headers = self._headers({'content-type': 'application/json'}) data = jsonutils.dumps({'name': 'testimg', 'type': 'kernel', 'foo': 'bar', 'disk_format': 'aki', 'container_format': 'aki'}) response = requests.post(path, headers=headers, data=data) self.assertEqual(201, response.status_code) image = jsonutils.loads(response.text) image_id = image['id'] # upload data path = self._url('/v2/images/%s/file' % image_id) headers = self._headers({'Content-Type': 'application/octet-stream'}) response = requests.put(path, headers=headers, data=data_src) self.assertEqual(expected_status, response.status_code) # Deletion should work path = self._url('/v2/images/%s' % image_id) response = requests.delete(path, headers=self._headers()) self.assertEqual(204, response.status_code) def test_image_upload_under_quota(self): data = 'x' * (self.user_storage_quota - 1) self._upload_image_test(data, 204) def test_image_upload_exceed_quota(self): data = 'x' * (self.user_storage_quota + 1) self._upload_image_test(data, 413) def test_chunked_image_upload_under_quota(self): def data_gen(): yield 'x' * (self.user_storage_quota - 1) self._upload_image_test(data_gen(), 204) def test_chunked_image_upload_exceed_quota(self): def data_gen(): yield 'x' * (self.user_storage_quota + 1) self._upload_image_test(data_gen(), 413) glance-2014.1/glance/tests/functional/v2/test_schemas.py0000664000175400017540000000437012323736226024322 0ustar jenkinsjenkins00000000000000# Copyright 2012 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import requests from glance.openstack.common import jsonutils from glance.tests import functional class TestSchemas(functional.FunctionalTest): def setUp(self): super(TestSchemas, self).setUp() self.cleanup() self.start_servers(**self.__dict__.copy()) def test_resource(self): # Ensure the image link works and custom properties are loaded path = 'http://%s:%d/v2/schemas/image' % ('127.0.0.1', self.api_port) response = requests.get(path) self.assertEqual(response.status_code, 200) image_schema = jsonutils.loads(response.text) expected = set([ 'id', 'name', 'visibility', 'checksum', 'created_at', 'updated_at', 'tags', 'size', 'virtual_size', 'owner', 'container_format', 'disk_format', 'self', 'file', 'status', 'schema', 'direct_url', 'locations', 'min_ram', 'min_disk', 'protected', ]) self.assertEqual(expected, set(image_schema['properties'].keys())) # Ensure the images link works and agrees with the image schema path = 'http://%s:%d/v2/schemas/images' % ('127.0.0.1', self.api_port) response = requests.get(path) self.assertEqual(response.status_code, 200) images_schema = jsonutils.loads(response.text) item_schema = images_schema['properties']['images']['items'] self.assertEqual(item_schema, image_schema) self.stop_servers() glance-2014.1/glance/tests/functional/v2/test_tasks.py0000664000175400017540000001133712323736226024025 0ustar jenkinsjenkins00000000000000# Copyright 2013 IBM Corp. # 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 os import uuid import fixtures import requests from glance.openstack.common import jsonutils from glance.tests import functional TENANT1 = str(uuid.uuid4()) TENANT2 = str(uuid.uuid4()) TENANT3 = str(uuid.uuid4()) TENANT4 = str(uuid.uuid4()) class TestTasks(functional.FunctionalTest): def setUp(self): super(TestTasks, self).setUp() self.cleanup() self.file_path = self._stash_file() self.api_server.deployment_flavor = 'noauth' self.start_servers(**self.__dict__.copy()) def _url(self, path): return 'http://127.0.0.1:%d%s' % (self.api_port, path) def _headers(self, custom_headers=None): base_headers = { 'X-Identity-Status': 'Confirmed', 'X-Auth-Token': '932c5c84-02ac-4fe5-a9ba-620af0e2bb96', 'X-User-Id': 'f9a41d13-0c13-47e9-bee2-ce4e8bfe958e', 'X-Tenant-Id': TENANT1, 'X-Roles': 'member', } base_headers.update(custom_headers or {}) return base_headers def _stash_file(self): self.tmp_dir = self.useFixture(fixtures.TempDir()).path self.store_dir = os.path.join(self.tmp_dir, 'images') os.mkdir(self.store_dir) file_path = os.path.join(self.store_dir, 'foo') with open(file_path, 'w') as f: f.write('blah') return 'file://%s' % file_path def test_task_lifecycle(self): # Task list should be empty path = self._url('/v2/tasks') response = requests.get(path, headers=self._headers()) self.assertEqual(200, response.status_code) tasks = jsonutils.loads(response.text)['tasks'] self.assertEqual(0, len(tasks)) # Create a task path = self._url('/v2/tasks') headers = self._headers({'content-type': 'application/json'}) data = jsonutils.dumps({ "type": "import", "input": { "import_from": self.file_path, "import_from_format": "qcow2", "image_properties": { 'disk_format': 'vhd', 'container_format': 'ovf' } } }) response = requests.post(path, headers=headers, data=data) self.assertEqual(201, response.status_code) # Returned task entity should have a generated id and status task = jsonutils.loads(response.text) task_id = task['id'] self.assertTrue('Location' in response.headers) self.assertEqual(path + '/' + task_id, response.headers['Location']) checked_keys = set([u'created_at', u'id', u'input', u'owner', u'schema', u'self', u'status', u'type', u'updated_at']) self.assertEqual(set(task.keys()), checked_keys) expected_task = { 'status': 'pending', 'type': 'import', 'input': { "import_from": self.file_path, "import_from_format": "qcow2", "image_properties": { 'disk_format': 'vhd', 'container_format': 'ovf' }}, 'schema': '/v2/schemas/task', } for key, value in expected_task.items(): self.assertEqual(task[key], value, key) # Tasks list should now have one entry path = self._url('/v2/tasks') response = requests.get(path, headers=self._headers()) self.assertEqual(200, response.status_code) tasks = jsonutils.loads(response.text)['tasks'] self.assertEqual(1, len(tasks)) self.assertEqual(tasks[0]['id'], task_id) # Attempt to delete a task path = self._url('/v2/tasks/%s' % tasks[0]['id']) response = requests.delete(path, headers=self._headers()) self.assertEqual(405, response.status_code) self.assertIsNotNone(response.headers.get('Allow')) self.assertEqual('GET', response.headers.get('Allow')) self.stop_servers() glance-2014.1/glance/tests/functional/v2/__init__.py0000664000175400017540000000000012323736226023361 0ustar jenkinsjenkins00000000000000glance-2014.1/glance/tests/functional/test_glance_manage.py0000664000175400017540000000573612323736226025120 0ustar jenkinsjenkins00000000000000# 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 cases for glance-manage""" import os import sys from glance.common import utils from glance.tests import functional from glance.tests.utils import depends_on_exe from glance.tests.utils import execute from glance.tests.utils import skip_if_disabled class TestGlanceManage(functional.FunctionalTest): """Functional tests for glance-manage""" def setUp(self): super(TestGlanceManage, self).setUp() conf_dir = os.path.join(self.test_dir, 'etc') utils.safe_mkdirs(conf_dir) self.conf_filepath = os.path.join(conf_dir, 'glance-manage.conf') self.db_filepath = os.path.join(self.test_dir, 'tests.sqlite') self.connection = ('sql_connection = sqlite:///%s' % self.db_filepath) def _sync_db(self, auto_create): with open(self.conf_filepath, 'wb') as conf_file: conf_file.write('[DEFAULT]\n') conf_file.write('db_auto_create = %r\n' % auto_create) conf_file.write(self.connection) conf_file.flush() cmd = ('%s -m glance.cmd.manage --config-file %s db sync' % (sys.executable, self.conf_filepath)) execute(cmd, raise_error=True) def _assert_tables(self): cmd = "sqlite3 %s '.schema'" % self.db_filepath exitcode, out, err = execute(cmd, raise_error=True) self.assertTrue('CREATE TABLE images' in out) self.assertTrue('CREATE TABLE image_tags' in out) self.assertTrue('CREATE TABLE image_locations' in out) #NOTE(bcwaldon): For some reason we need double-quotes around # these two table names # NOTE(vsergeyev): There are some cases when we have no double-quotes self.assertTrue( 'CREATE TABLE "image_members"' in out or 'CREATE TABLE image_members' in out) self.assertTrue( 'CREATE TABLE "image_properties"' in out or 'CREATE TABLE image_properties' in out) @depends_on_exe('sqlite3') @skip_if_disabled def test_db_creation(self): """Test DB creation by db_sync on a fresh DB""" self._sync_db(True) self._assert_tables() @depends_on_exe('sqlite3') @skip_if_disabled def test_db_creation_auto_create_overridden(self): """Test DB creation with db_auto_create False""" self._sync_db(False) self._assert_tables() glance-2014.1/glance/tests/functional/test_api.py0000664000175400017540000002625512323736226023127 0ustar jenkinsjenkins00000000000000# Copyright 2012 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """Version-independent api tests""" import httplib2 from glance.openstack.common import jsonutils from glance.tests import functional class TestRootApi(functional.FunctionalTest): def test_version_configurations(self): """Test that versioning is handled properly through all channels""" #v1 and v2 api enabled self.cleanup() self.start_servers(**self.__dict__.copy()) url = 'http://127.0.0.1:%d/v%%s/' % self.api_port versions = {'versions': [ { 'id': 'v2.2', 'status': 'CURRENT', 'links': [{'rel': 'self', 'href': url % '2'}], }, { 'id': 'v2.1', 'status': 'SUPPORTED', 'links': [{'rel': 'self', 'href': url % '2'}], }, { 'id': 'v2.0', 'status': 'SUPPORTED', 'links': [{'rel': 'self', 'href': url % '2'}], }, { 'id': 'v1.1', 'status': 'CURRENT', 'links': [{'rel': 'self', 'href': url % '1'}], }, { 'id': 'v1.0', 'status': 'SUPPORTED', 'links': [{'rel': 'self', 'href': url % '1'}], }, ]} versions_json = jsonutils.dumps(versions) # Verify version choices returned. path = 'http://%s:%d' % ('127.0.0.1', self.api_port) http = httplib2.Http() response, content = http.request(path, 'GET') self.assertEqual(response.status, 300) self.assertEqual(content, versions_json) self.stop_servers() #v2 api enabled self.cleanup() self.api_server.enable_v1_api = False self.api_server.enable_v2_api = True self.start_servers(**self.__dict__.copy()) url = 'http://127.0.0.1:%d/v%%s/' % self.api_port versions = {'versions': [ { 'id': 'v2.2', 'status': 'CURRENT', 'links': [{'rel': 'self', 'href': url % '2'}], }, { 'id': 'v2.1', 'status': 'SUPPORTED', 'links': [{'rel': 'self', 'href': url % '2'}], }, { 'id': 'v2.0', 'status': 'SUPPORTED', 'links': [{'rel': 'self', 'href': url % '2'}], }, ]} versions_json = jsonutils.dumps(versions) # Verify version choices returned. path = 'http://%s:%d' % ('127.0.0.1', self.api_port) http = httplib2.Http() response, content = http.request(path, 'GET') self.assertEqual(response.status, 300) self.assertEqual(content, versions_json) self.stop_servers() #v1 api enabled self.cleanup() self.api_server.enable_v1_api = True self.api_server.enable_v2_api = False self.start_servers(**self.__dict__.copy()) url = 'http://127.0.0.1:%d/v%%s/' % self.api_port versions = {'versions': [ { 'id': 'v1.1', 'status': 'CURRENT', 'links': [{'rel': 'self', 'href': url % '1'}], }, { 'id': 'v1.0', 'status': 'SUPPORTED', 'links': [{'rel': 'self', 'href': url % '1'}], }, ]} versions_json = jsonutils.dumps(versions) # Verify version choices returned. path = 'http://%s:%d' % ('127.0.0.1', self.api_port) http = httplib2.Http() response, content = http.request(path, 'GET') self.assertEqual(response.status, 300) self.assertEqual(content, versions_json) self.stop_servers() def test_version_variations(self): """Test that versioning is handled properly through all channels""" self.cleanup() self.start_servers(**self.__dict__.copy()) url = 'http://127.0.0.1:%d/v%%s/' % self.api_port versions = {'versions': [ { 'id': 'v2.2', 'status': 'CURRENT', 'links': [{'rel': 'self', 'href': url % '2'}], }, { 'id': 'v2.1', 'status': 'SUPPORTED', 'links': [{'rel': 'self', 'href': url % '2'}], }, { 'id': 'v2.0', 'status': 'SUPPORTED', 'links': [{'rel': 'self', 'href': url % '2'}], }, { 'id': 'v1.1', 'status': 'CURRENT', 'links': [{'rel': 'self', 'href': url % '1'}], }, { 'id': 'v1.0', 'status': 'SUPPORTED', 'links': [{'rel': 'self', 'href': url % '1'}], }, ]} versions_json = jsonutils.dumps(versions) images = {'images': []} images_json = jsonutils.dumps(images) # 0. GET / with no Accept: header # Verify version choices returned. # Bug lp:803260 no Accept header causes a 500 in glance-api path = 'http://%s:%d' % ('127.0.0.1', self.api_port) http = httplib2.Http() response, content = http.request(path, 'GET') self.assertEqual(response.status, 300) self.assertEqual(content, versions_json) # 1. GET /images with no Accept: header # Verify version choices returned. path = 'http://%s:%d/images' % ('127.0.0.1', self.api_port) http = httplib2.Http() response, content = http.request(path, 'GET') self.assertEqual(response.status, 300) self.assertEqual(content, versions_json) # 2. GET /v1/images with no Accept: header # Verify empty images list returned. path = 'http://%s:%d/v1/images' % ('127.0.0.1', self.api_port) http = httplib2.Http() response, content = http.request(path, 'GET') self.assertEqual(response.status, 200) self.assertEqual(content, images_json) # 3. GET / with Accept: unknown header # Verify version choices returned. Verify message in API log about # unknown accept header. path = 'http://%s:%d/' % ('127.0.0.1', self.api_port) http = httplib2.Http() headers = {'Accept': 'unknown'} response, content = http.request(path, 'GET', headers=headers) self.assertEqual(response.status, 300) self.assertEqual(content, versions_json) # 4. GET / with an Accept: application/vnd.openstack.images-v1 # Verify empty image list returned path = 'http://%s:%d/images' % ('127.0.0.1', self.api_port) http = httplib2.Http() headers = {'Accept': 'application/vnd.openstack.images-v1'} response, content = http.request(path, 'GET', headers=headers) self.assertEqual(response.status, 200) self.assertEqual(content, images_json) # 5. GET /images with a Accept: application/vnd.openstack.compute-v1 # header. Verify version choices returned. Verify message in API log # about unknown accept header. path = 'http://%s:%d/images' % ('127.0.0.1', self.api_port) http = httplib2.Http() headers = {'Accept': 'application/vnd.openstack.compute-v1'} response, content = http.request(path, 'GET', headers=headers) self.assertEqual(response.status, 300) self.assertEqual(content, versions_json) # 6. GET /v1.0/images with no Accept: header # Verify version choices returned path = 'http://%s:%d/v1.a/images' % ('127.0.0.1', self.api_port) http = httplib2.Http() response, content = http.request(path, 'GET') self.assertEqual(response.status, 300) # 7. GET /v1.a/images with no Accept: header # Verify version choices returned path = 'http://%s:%d/v1.a/images' % ('127.0.0.1', self.api_port) http = httplib2.Http() response, content = http.request(path, 'GET') self.assertEqual(response.status, 300) # 8. GET /va.1/images with no Accept: header # Verify version choices returned path = 'http://%s:%d/va.1/images' % ('127.0.0.1', self.api_port) http = httplib2.Http() response, content = http.request(path, 'GET') self.assertEqual(response.status, 300) self.assertEqual(content, versions_json) # 9. GET /versions with no Accept: header # Verify version choices returned path = 'http://%s:%d/versions' % ('127.0.0.1', self.api_port) http = httplib2.Http() response, content = http.request(path, 'GET') self.assertEqual(response.status, 300) self.assertEqual(content, versions_json) # 10. GET /versions with a Accept: application/vnd.openstack.images-v1 # header. Verify version choices returned. path = 'http://%s:%d/versions' % ('127.0.0.1', self.api_port) http = httplib2.Http() headers = {'Accept': 'application/vnd.openstack.images-v1'} response, content = http.request(path, 'GET', headers=headers) self.assertEqual(response.status, 300) self.assertEqual(content, versions_json) # 11. GET /v1/versions with no Accept: header # Verify 404 returned path = 'http://%s:%d/v1/versions' % ('127.0.0.1', self.api_port) http = httplib2.Http() response, content = http.request(path, 'GET') self.assertEqual(response.status, 404) # Verify version choices returned path = 'http://%s:%d/v10' % ('127.0.0.1', self.api_port) http = httplib2.Http() response, content = http.request(path, 'GET') self.assertEqual(response.status, 300) self.assertEqual(content, versions_json) # 13. GET /images with a Accept: application/vnd.openstack.compute-v2 # header. Verify version choices returned. Verify message in API log # about unknown version in accept header. path = 'http://%s:%d/images' % ('127.0.0.1', self.api_port) http = httplib2.Http() headers = {'Accept': 'application/vnd.openstack.images-v10'} response, content = http.request(path, 'GET', headers=headers) self.assertEqual(response.status, 300) self.assertEqual(content, versions_json) # 14. GET /v1.2/images with no Accept: header # Verify version choices returned path = 'http://%s:%d/v1.2/images' % ('127.0.0.1', self.api_port) http = httplib2.Http() response, content = http.request(path, 'GET') self.assertEqual(response.status, 300) self.assertEqual(content, versions_json) self.stop_servers() glance-2014.1/glance/tests/functional/test_cache_middleware.py0000664000175400017540000010016412323736226025606 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ Tests a Glance API server which uses the caching middleware that uses the default SQLite cache driver. We use the filesystem store, but that is really not relevant, as the image cache is transparent to the backend store. """ import hashlib import os import shutil import sys import time import httplib2 from six.moves import xrange from glance.openstack.common import jsonutils from glance.openstack.common import units from glance.tests import functional from glance.tests.utils import execute from glance.tests.utils import minimal_headers from glance.tests.utils import skip_if_disabled from glance.tests.utils import xattr_writes_supported from glance.tests.functional.store_utils import get_http_uri from glance.tests.functional.store_utils import setup_http FIVE_KB = 5 * units.Ki class BaseCacheMiddlewareTest(object): @skip_if_disabled def test_cache_middleware_transparent_v1(self): """ We test that putting the cache middleware into the application pipeline gives us transparent image caching """ self.cleanup() self.start_servers(**self.__dict__.copy()) # Add an image and verify a 200 OK is returned image_data = "*" * FIVE_KB headers = minimal_headers('Image1') path = "http://%s:%d/v1/images" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, 'POST', headers=headers, body=image_data) self.assertEqual(response.status, 201) data = jsonutils.loads(content) self.assertEqual(data['image']['checksum'], hashlib.md5(image_data).hexdigest()) self.assertEqual(data['image']['size'], FIVE_KB) self.assertEqual(data['image']['name'], "Image1") self.assertEqual(data['image']['is_public'], True) image_id = data['image']['id'] # Verify image not in cache image_cached_path = os.path.join(self.api_server.image_cache_dir, image_id) self.assertFalse(os.path.exists(image_cached_path)) # Grab the image path = "http://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port, image_id) http = httplib2.Http() response, content = http.request(path, 'GET') self.assertEqual(response.status, 200) # Verify image now in cache image_cached_path = os.path.join(self.api_server.image_cache_dir, image_id) # You might wonder why the heck this is here... well, it's here # because it took me forever to figure out that the disk write # cache in Linux was causing random failures of the os.path.exists # assert directly below this. Basically, since the cache is writing # the image file to disk in a different process, the write buffers # don't flush the cache file during an os.rename() properly, resulting # in a false negative on the file existence check below. This little # loop pauses the execution of this process for no more than 1.5 # seconds. If after that time the cached image file still doesn't # appear on disk, something really is wrong, and the assert should # trigger... i = 0 while not os.path.exists(image_cached_path) and i < 30: time.sleep(0.05) i = i + 1 self.assertTrue(os.path.exists(image_cached_path)) # Now, we delete the image from the server and verify that # the image cache no longer contains the deleted image path = "http://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port, image_id) http = httplib2.Http() response, content = http.request(path, 'DELETE') self.assertEqual(response.status, 200) self.assertFalse(os.path.exists(image_cached_path)) self.stop_servers() @skip_if_disabled def test_cache_middleware_transparent_v2(self): """Ensure the v2 API image transfer calls trigger caching""" self.cleanup() self.start_servers(**self.__dict__.copy()) # Add an image and verify success path = "http://%s:%d/v2/images" % ("0.0.0.0", self.api_port) http = httplib2.Http() headers = {'content-type': 'application/json'} image_entity = { 'name': 'Image1', 'visibility': 'public', 'container_format': 'bare', 'disk_format': 'raw', } response, content = http.request(path, 'POST', headers=headers, body=jsonutils.dumps(image_entity)) self.assertEqual(response.status, 201) data = jsonutils.loads(content) image_id = data['id'] path = "http://%s:%d/v2/images/%s/file" % ("0.0.0.0", self.api_port, image_id) headers = {'content-type': 'application/octet-stream'} image_data = "*" * FIVE_KB response, content = http.request(path, 'PUT', headers=headers, body=image_data) self.assertEqual(response.status, 204) # Verify image not in cache image_cached_path = os.path.join(self.api_server.image_cache_dir, image_id) self.assertFalse(os.path.exists(image_cached_path)) # Grab the image http = httplib2.Http() response, content = http.request(path, 'GET') self.assertEqual(response.status, 200) # Verify image now in cache image_cached_path = os.path.join(self.api_server.image_cache_dir, image_id) # Now, we delete the image from the server and verify that # the image cache no longer contains the deleted image path = "http://%s:%d/v2/images/%s" % ("0.0.0.0", self.api_port, image_id) http = httplib2.Http() response, content = http.request(path, 'DELETE') self.assertEqual(response.status, 204) self.assertFalse(os.path.exists(image_cached_path)) self.stop_servers() @skip_if_disabled def test_cache_remote_image(self): """ We test that caching is no longer broken for remote images """ self.cleanup() self.start_servers(**self.__dict__.copy()) setup_http(self) # Add a remote image and verify a 201 Created is returned remote_uri = get_http_uri(self, '2') headers = {'X-Image-Meta-Name': 'Image2', 'X-Image-Meta-disk_format': 'raw', 'X-Image-Meta-container_format': 'ovf', 'X-Image-Meta-Is-Public': 'True', 'X-Image-Meta-Location': remote_uri} path = "http://%s:%d/v1/images" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, 'POST', headers=headers) self.assertEqual(response.status, 201) data = jsonutils.loads(content) self.assertEqual(data['image']['size'], FIVE_KB) image_id = data['image']['id'] path = "http://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port, image_id) # Grab the image http = httplib2.Http() response, content = http.request(path, 'GET') self.assertEqual(response.status, 200) # Grab the image again to ensure it can be served out from # cache with the correct size http = httplib2.Http() response, content = http.request(path, 'GET') self.assertEqual(response.status, 200) self.assertEqual(int(response['content-length']), FIVE_KB) self.stop_servers() @skip_if_disabled def test_cache_middleware_trans_v1_without_download_image_policy(self): """ Ensure the image v1 API image transfer applied 'download_image' policy enforcement. """ self.cleanup() self.start_servers(**self.__dict__.copy()) # Add an image and verify a 200 OK is returned image_data = "*" * FIVE_KB headers = minimal_headers('Image1') path = "http://%s:%d/v1/images" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, 'POST', headers=headers, body=image_data) self.assertEqual(response.status, 201) data = jsonutils.loads(content) self.assertEqual(data['image']['checksum'], hashlib.md5(image_data).hexdigest()) self.assertEqual(data['image']['size'], FIVE_KB) self.assertEqual(data['image']['name'], "Image1") self.assertEqual(data['image']['is_public'], True) image_id = data['image']['id'] # Verify image not in cache image_cached_path = os.path.join(self.api_server.image_cache_dir, image_id) self.assertFalse(os.path.exists(image_cached_path)) rules = {"context_is_admin": "role:admin", "default": "", "download_image": "!"} self.set_policy_rules(rules) # Grab the image path = "http://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port, image_id) http = httplib2.Http() response, content = http.request(path, 'GET') self.assertEqual(response.status, 403) # Now, we delete the image from the server and verify that # the image cache no longer contains the deleted image path = "http://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port, image_id) http = httplib2.Http() response, content = http.request(path, 'DELETE') self.assertEqual(response.status, 200) self.assertFalse(os.path.exists(image_cached_path)) self.stop_servers() @skip_if_disabled def test_cache_middleware_trans_v2_without_download_image_policy(self): """ Ensure the image v2 API image transfer applied 'download_image' policy enforcement. """ self.cleanup() self.start_servers(**self.__dict__.copy()) # Add an image and verify success path = "http://%s:%d/v2/images" % ("0.0.0.0", self.api_port) http = httplib2.Http() headers = {'content-type': 'application/json'} image_entity = { 'name': 'Image1', 'visibility': 'public', 'container_format': 'bare', 'disk_format': 'raw', } response, content = http.request(path, 'POST', headers=headers, body=jsonutils.dumps(image_entity)) self.assertEqual(response.status, 201) data = jsonutils.loads(content) image_id = data['id'] path = "http://%s:%d/v2/images/%s/file" % ("0.0.0.0", self.api_port, image_id) headers = {'content-type': 'application/octet-stream'} image_data = "*" * FIVE_KB response, content = http.request(path, 'PUT', headers=headers, body=image_data) self.assertEqual(response.status, 204) # Verify image not in cache image_cached_path = os.path.join(self.api_server.image_cache_dir, image_id) self.assertFalse(os.path.exists(image_cached_path)) rules = {"context_is_admin": "role:admin", "default": "", "download_image": "!"} self.set_policy_rules(rules) # Grab the image http = httplib2.Http() response, content = http.request(path, 'GET') self.assertEqual(response.status, 403) # Now, we delete the image from the server and verify that # the image cache no longer contains the deleted image path = "http://%s:%d/v2/images/%s" % ("0.0.0.0", self.api_port, image_id) http = httplib2.Http() response, content = http.request(path, 'DELETE') self.assertEqual(response.status, 204) self.assertFalse(os.path.exists(image_cached_path)) self.stop_servers() class BaseCacheManageMiddlewareTest(object): """Base test class for testing cache management middleware""" def verify_no_images(self): path = "http://%s:%d/v1/images" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertTrue('images' in data) self.assertEqual(0, len(data['images'])) def add_image(self, name): """ Adds an image and returns the newly-added image identifier """ image_data = "*" * FIVE_KB headers = minimal_headers('%s' % name) path = "http://%s:%d/v1/images" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, 'POST', headers=headers, body=image_data) self.assertEqual(response.status, 201) data = jsonutils.loads(content) self.assertEqual(data['image']['checksum'], hashlib.md5(image_data).hexdigest()) self.assertEqual(data['image']['size'], FIVE_KB) self.assertEqual(data['image']['name'], name) self.assertEqual(data['image']['is_public'], True) return data['image']['id'] def verify_no_cached_images(self): """ Verify no images in the image cache """ path = "http://%s:%d/v1/cached_images" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertTrue('cached_images' in data) self.assertEqual(data['cached_images'], []) @skip_if_disabled def test_user_not_authorized(self): self.cleanup() self.start_servers(**self.__dict__.copy()) self.verify_no_images() image_id1 = self.add_image("Image1") image_id2 = self.add_image("Image2") # Verify image does not yet show up in cache (we haven't "hit" # it yet using a GET /images/1 ... self.verify_no_cached_images() # Grab the image path = "http://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port, image_id1) http = httplib2.Http() response, content = http.request(path, 'GET') self.assertEqual(response.status, 200) # Verify image now in cache path = "http://%s:%d/v1/cached_images" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertTrue('cached_images' in data) cached_images = data['cached_images'] self.assertEqual(1, len(cached_images)) self.assertEqual(image_id1, cached_images[0]['image_id']) # Set policy to disallow access to cache management rules = {"manage_image_cache": '!'} self.set_policy_rules(rules) # Verify an unprivileged user cannot see cached images path = "http://%s:%d/v1/cached_images" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, 'GET') self.assertEqual(response.status, 403) # Verify an unprivileged user cannot delete images from the cache path = "http://%s:%d/v1/cached_images/%s" % ("127.0.0.1", self.api_port, image_id1) http = httplib2.Http() response, content = http.request(path, 'DELETE') self.assertEqual(response.status, 403) # Verify an unprivileged user cannot delete all cached images path = "http://%s:%d/v1/cached_images" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, 'DELETE') self.assertEqual(response.status, 403) # Verify an unprivileged user cannot queue an image path = "http://%s:%d/v1/queued_images/%s" % ("127.0.0.1", self.api_port, image_id2) http = httplib2.Http() response, content = http.request(path, 'PUT') self.assertEqual(response.status, 403) self.stop_servers() @skip_if_disabled def test_cache_manage_get_cached_images(self): """ Tests that cached images are queryable """ self.cleanup() self.start_servers(**self.__dict__.copy()) self.verify_no_images() image_id = self.add_image("Image1") # Verify image does not yet show up in cache (we haven't "hit" # it yet using a GET /images/1 ... self.verify_no_cached_images() # Grab the image path = "http://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port, image_id) http = httplib2.Http() response, content = http.request(path, 'GET') self.assertEqual(response.status, 200) # Verify image now in cache path = "http://%s:%d/v1/cached_images" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertTrue('cached_images' in data) # Verify the last_modified/last_accessed values are valid floats for cached_image in data['cached_images']: for time_key in ('last_modified', 'last_accessed'): time_val = cached_image[time_key] try: float(time_val) except ValueError: self.fail('%s time %s for cached image %s not a valid ' 'float' % (time_key, time_val, cached_image['image_id'])) cached_images = data['cached_images'] self.assertEqual(1, len(cached_images)) self.assertEqual(image_id, cached_images[0]['image_id']) self.assertEqual(0, cached_images[0]['hits']) # Hit the image path = "http://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port, image_id) http = httplib2.Http() response, content = http.request(path, 'GET') self.assertEqual(response.status, 200) # Verify image hits increased in output of manage GET path = "http://%s:%d/v1/cached_images" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertTrue('cached_images' in data) cached_images = data['cached_images'] self.assertEqual(1, len(cached_images)) self.assertEqual(image_id, cached_images[0]['image_id']) self.assertEqual(1, cached_images[0]['hits']) self.stop_servers() @skip_if_disabled def test_cache_manage_delete_cached_images(self): """ Tests that cached images may be deleted """ self.cleanup() self.start_servers(**self.__dict__.copy()) self.verify_no_images() ids = {} # Add a bunch of images... for x in xrange(4): ids[x] = self.add_image("Image%s" % str(x)) # Verify no images in cached_images because no image has been hit # yet using a GET /images/ ... self.verify_no_cached_images() # Grab the images, essentially caching them... for x in xrange(4): path = "http://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port, ids[x]) http = httplib2.Http() response, content = http.request(path, 'GET') self.assertEqual(response.status, 200, "Failed to find image %s" % ids[x]) # Verify images now in cache path = "http://%s:%d/v1/cached_images" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertTrue('cached_images' in data) cached_images = data['cached_images'] self.assertEqual(4, len(cached_images)) for x in xrange(4, 0): # Cached images returned last modified order self.assertEqual(ids[x], cached_images[x]['image_id']) self.assertEqual(0, cached_images[x]['hits']) # Delete third image of the cached images and verify no longer in cache path = "http://%s:%d/v1/cached_images/%s" % ("127.0.0.1", self.api_port, ids[2]) http = httplib2.Http() response, content = http.request(path, 'DELETE') self.assertEqual(response.status, 200) path = "http://%s:%d/v1/cached_images" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertTrue('cached_images' in data) cached_images = data['cached_images'] self.assertEqual(3, len(cached_images)) self.assertTrue(ids[2] not in [x['image_id'] for x in cached_images]) # Delete all cached images and verify nothing in cache path = "http://%s:%d/v1/cached_images" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, 'DELETE') self.assertEqual(response.status, 200) path = "http://%s:%d/v1/cached_images" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertTrue('cached_images' in data) cached_images = data['cached_images'] self.assertEqual(0, len(cached_images)) self.stop_servers() @skip_if_disabled def test_cache_manage_delete_queued_images(self): """ Tests that all queued images may be deleted at once """ self.cleanup() self.start_servers(**self.__dict__.copy()) self.verify_no_images() ids = {} NUM_IMAGES = 4 # Add and then queue some images for x in xrange(NUM_IMAGES): ids[x] = self.add_image("Image%s" % str(x)) path = "http://%s:%d/v1/queued_images/%s" % ("127.0.0.1", self.api_port, ids[x]) http = httplib2.Http() response, content = http.request(path, 'PUT') self.assertEqual(response.status, 200) # Delete all queued images path = "http://%s:%d/v1/queued_images" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, 'DELETE') self.assertEqual(response.status, 200) data = jsonutils.loads(content) num_deleted = data['num_deleted'] self.assertEqual(NUM_IMAGES, num_deleted) # Verify a second delete now returns num_deleted=0 path = "http://%s:%d/v1/queued_images" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, 'DELETE') self.assertEqual(response.status, 200) data = jsonutils.loads(content) num_deleted = data['num_deleted'] self.assertEqual(0, num_deleted) self.stop_servers() @skip_if_disabled def test_queue_and_prefetch(self): """ Tests that images may be queued and prefetched """ self.cleanup() self.start_servers(**self.__dict__.copy()) cache_config_filepath = os.path.join(self.test_dir, 'etc', 'glance-cache.conf') cache_file_options = { 'image_cache_dir': self.api_server.image_cache_dir, 'image_cache_driver': self.image_cache_driver, 'registry_port': self.registry_server.bind_port, 'log_file': os.path.join(self.test_dir, 'cache.log'), 'metadata_encryption_key': "012345678901234567890123456789ab" } with open(cache_config_filepath, 'w') as cache_file: cache_file.write("""[DEFAULT] debug = True verbose = True image_cache_dir = %(image_cache_dir)s image_cache_driver = %(image_cache_driver)s registry_host = 127.0.0.1 registry_port = %(registry_port)s metadata_encryption_key = %(metadata_encryption_key)s log_file = %(log_file)s """ % cache_file_options) self.verify_no_images() ids = {} # Add a bunch of images... for x in xrange(4): ids[x] = self.add_image("Image%s" % str(x)) # Queue the first image, verify no images still in cache after queueing # then run the prefetcher and verify that the image is then in the # cache path = "http://%s:%d/v1/queued_images/%s" % ("127.0.0.1", self.api_port, ids[0]) http = httplib2.Http() response, content = http.request(path, 'PUT') self.assertEqual(response.status, 200) self.verify_no_cached_images() cmd = ("%s -m glance.cmd.cache_prefetcher --config-file %s" % (sys.executable, cache_config_filepath)) exitcode, out, err = execute(cmd) self.assertEqual(0, exitcode) self.assertEqual('', out.strip(), out) # Verify first image now in cache path = "http://%s:%d/v1/cached_images" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertTrue('cached_images' in data) cached_images = data['cached_images'] self.assertEqual(1, len(cached_images)) self.assertTrue(ids[0] in [r['image_id'] for r in data['cached_images']]) self.stop_servers() class TestImageCacheXattr(functional.FunctionalTest, BaseCacheMiddlewareTest): """Functional tests that exercise the image cache using the xattr driver""" def setUp(self): """ Test to see if the pre-requisites for the image cache are working (python-xattr installed and xattr support on the filesystem) """ if getattr(self, 'disabled', False): return if not getattr(self, 'inited', False): try: import xattr # noqa except ImportError: self.inited = True self.disabled = True self.disabled_message = ("python-xattr not installed.") return self.inited = True self.disabled = False self.image_cache_driver = "xattr" super(TestImageCacheXattr, self).setUp() self.api_server.deployment_flavor = "caching" if not xattr_writes_supported(self.test_dir): self.inited = True self.disabled = True self.disabled_message = ("filesystem does not support xattr") return def tearDown(self): super(TestImageCacheXattr, self).tearDown() if os.path.exists(self.api_server.image_cache_dir): shutil.rmtree(self.api_server.image_cache_dir) class TestImageCacheManageXattr(functional.FunctionalTest, BaseCacheManageMiddlewareTest): """ Functional tests that exercise the image cache management with the Xattr cache driver """ def setUp(self): """ Test to see if the pre-requisites for the image cache are working (python-xattr installed and xattr support on the filesystem) """ if getattr(self, 'disabled', False): return if not getattr(self, 'inited', False): try: import xattr # noqa except ImportError: self.inited = True self.disabled = True self.disabled_message = ("python-xattr not installed.") return self.inited = True self.disabled = False self.image_cache_driver = "xattr" super(TestImageCacheManageXattr, self).setUp() self.api_server.deployment_flavor = "cachemanagement" if not xattr_writes_supported(self.test_dir): self.inited = True self.disabled = True self.disabled_message = ("filesystem does not support xattr") return def tearDown(self): super(TestImageCacheManageXattr, self).tearDown() if os.path.exists(self.api_server.image_cache_dir): shutil.rmtree(self.api_server.image_cache_dir) class TestImageCacheSqlite(functional.FunctionalTest, BaseCacheMiddlewareTest): """ Functional tests that exercise the image cache using the SQLite driver """ def setUp(self): """ Test to see if the pre-requisites for the image cache are working (python-xattr installed and xattr support on the filesystem) """ if getattr(self, 'disabled', False): return if not getattr(self, 'inited', False): try: import sqlite3 # noqa except ImportError: self.inited = True self.disabled = True self.disabled_message = ("python-sqlite3 not installed.") return self.inited = True self.disabled = False super(TestImageCacheSqlite, self).setUp() self.api_server.deployment_flavor = "caching" def tearDown(self): super(TestImageCacheSqlite, self).tearDown() if os.path.exists(self.api_server.image_cache_dir): shutil.rmtree(self.api_server.image_cache_dir) class TestImageCacheManageSqlite(functional.FunctionalTest, BaseCacheManageMiddlewareTest): """ Functional tests that exercise the image cache management using the SQLite driver """ def setUp(self): """ Test to see if the pre-requisites for the image cache are working (python-xattr installed and xattr support on the filesystem) """ if getattr(self, 'disabled', False): return if not getattr(self, 'inited', False): try: import sqlite3 # noqa except ImportError: self.inited = True self.disabled = True self.disabled_message = ("python-sqlite3 not installed.") return self.inited = True self.disabled = False self.image_cache_driver = "sqlite" super(TestImageCacheManageSqlite, self).setUp() self.api_server.deployment_flavor = "cachemanagement" def tearDown(self): super(TestImageCacheManageSqlite, self).tearDown() if os.path.exists(self.api_server.image_cache_dir): shutil.rmtree(self.api_server.image_cache_dir) glance-2014.1/glance/tests/functional/test_bin_glance_cache_manage.py0000664000175400017540000002634212323736226027067 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """Functional test case that utilizes the bin/glance-cache-manage CLI tool""" import datetime import hashlib import httplib2 import os import sys from six.moves import xrange from glance.openstack.common import jsonutils from glance.openstack.common import units from glance.tests import functional from glance.tests.utils import execute from glance.tests.utils import minimal_headers FIVE_KB = 5 * units.Ki class TestBinGlanceCacheManage(functional.FunctionalTest): """Functional tests for the bin/glance CLI tool""" def setUp(self): self.image_cache_driver = "sqlite" super(TestBinGlanceCacheManage, self).setUp() self.api_server.deployment_flavor = "cachemanagement" # NOTE(sirp): This is needed in case we are running the tests under an # environment in which OS_AUTH_STRATEGY=keystone. The test server we # spin up won't have keystone support, so we need to switch to the # NoAuth strategy. os.environ['OS_AUTH_STRATEGY'] = 'noauth' os.environ['OS_AUTH_URL'] = '' def add_image(self, name): """ Adds an image with supplied name and returns the newly-created image identifier. """ image_data = "*" * FIVE_KB headers = minimal_headers(name) path = "http://%s:%d/v1/images" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, 'POST', headers=headers, body=image_data) self.assertEqual(response.status, 201) data = jsonutils.loads(content) self.assertEqual(data['image']['checksum'], hashlib.md5(image_data).hexdigest()) self.assertEqual(data['image']['size'], FIVE_KB) self.assertEqual(data['image']['name'], name) self.assertEqual(data['image']['is_public'], True) return data['image']['id'] def is_image_cached(self, image_id): """ Return True if supplied image ID is cached, False otherwise """ exe_cmd = '%s -m glance.cmd.cache_manage' % sys.executable cmd = "%s --port=%d list-cached" % (exe_cmd, self.api_port) exitcode, out, err = execute(cmd) self.assertEqual(0, exitcode) return image_id in out def iso_date(self, image_id): """ Return True if supplied image ID is cached, False otherwise """ exe_cmd = '%s -m glance.cmd.cache_manage' % sys.executable cmd = "%s --port=%d list-cached" % (exe_cmd, self.api_port) exitcode, out, err = execute(cmd) return datetime.datetime.utcnow().strftime("%Y-%m-%d") in out def test_no_cache_enabled(self): """ Test that cache index command works """ self.cleanup() self.api_server.deployment_flavor = '' self.start_servers() # Not passing in cache_manage in pipeline... api_port = self.api_port # Verify decent error message returned exe_cmd = '%s -m glance.cmd.cache_manage' % sys.executable cmd = "%s --port=%d list-cached" % (exe_cmd, api_port) exitcode, out, err = execute(cmd, raise_error=False) self.assertEqual(1, exitcode) self.assertTrue('Cache management middleware not enabled on host' in out.strip()) self.stop_servers() def test_cache_index(self): """ Test that cache index command works """ self.cleanup() self.start_servers(**self.__dict__.copy()) api_port = self.api_port # Verify no cached images exe_cmd = '%s -m glance.cmd.cache_manage' % sys.executable cmd = "%s --port=%d list-cached" % (exe_cmd, api_port) exitcode, out, err = execute(cmd) self.assertEqual(0, exitcode) self.assertTrue('No cached images' in out.strip()) ids = {} # Add a few images and cache the second one of them # by GETing the image... for x in xrange(4): ids[x] = self.add_image("Image%s" % x) path = "http://%s:%d/v1/images/%s" % ("127.0.0.1", api_port, ids[1]) http = httplib2.Http() response, content = http.request(path, 'GET') self.assertEqual(response.status, 200) self.assertTrue(self.is_image_cached(ids[1]), "%s is not cached." % ids[1]) self.assertTrue(self.iso_date(ids[1])) self.stop_servers() def test_queue(self): """ Test that we can queue and fetch images using the CLI utility """ self.cleanup() self.start_servers(**self.__dict__.copy()) api_port = self.api_port # Verify no cached images exe_cmd = '%s -m glance.cmd.cache_manage' % sys.executable cmd = "%s --port=%d list-cached" % (exe_cmd, api_port) exitcode, out, err = execute(cmd) self.assertEqual(0, exitcode) self.assertTrue('No cached images' in out.strip()) # Verify no queued images cmd = "%s --port=%d list-queued" % (exe_cmd, api_port) exitcode, out, err = execute(cmd) self.assertEqual(0, exitcode) self.assertTrue('No queued images' in out.strip()) ids = {} # Add a few images and cache the second one of them # by GETing the image... for x in xrange(4): ids[x] = self.add_image("Image%s" % x) # Queue second image and then cache it cmd = "%s --port=%d --force queue-image %s" % ( exe_cmd, api_port, ids[1]) exitcode, out, err = execute(cmd) self.assertEqual(0, exitcode) # Verify queued second image cmd = "%s --port=%d list-queued" % (exe_cmd, api_port) exitcode, out, err = execute(cmd) self.assertEqual(0, exitcode) self.assertTrue(ids[1] in out, 'Image %s was not queued!' % ids[1]) # Cache images in the queue by running the prefetcher cache_config_filepath = os.path.join(self.test_dir, 'etc', 'glance-cache.conf') cache_file_options = { 'image_cache_dir': self.api_server.image_cache_dir, 'image_cache_driver': self.image_cache_driver, 'registry_port': self.registry_server.bind_port, 'log_file': os.path.join(self.test_dir, 'cache.log'), 'metadata_encryption_key': "012345678901234567890123456789ab" } with open(cache_config_filepath, 'w') as cache_file: cache_file.write("""[DEFAULT] debug = True verbose = True image_cache_dir = %(image_cache_dir)s image_cache_driver = %(image_cache_driver)s registry_host = 127.0.0.1 registry_port = %(registry_port)s metadata_encryption_key = %(metadata_encryption_key)s log_file = %(log_file)s """ % cache_file_options) cmd = ("%s -m glance.cmd.cache_prefetcher --config-file %s" % (sys.executable, cache_config_filepath)) exitcode, out, err = execute(cmd) self.assertEqual(0, exitcode) self.assertEqual('', out.strip(), out) # Verify no queued images cmd = "%s --port=%d list-queued" % (exe_cmd, api_port) exitcode, out, err = execute(cmd) self.assertEqual(0, exitcode) self.assertTrue('No queued images' in out.strip()) # Verify second image now cached cmd = "%s --port=%d list-cached" % (exe_cmd, api_port) exitcode, out, err = execute(cmd) self.assertEqual(0, exitcode) self.assertTrue(ids[1] in out, 'Image %s was not cached!' % ids[1]) # Queue third image and then delete it from queue cmd = "%s --port=%d --force queue-image %s" % ( exe_cmd, api_port, ids[2]) exitcode, out, err = execute(cmd) self.assertEqual(0, exitcode) # Verify queued third image cmd = "%s --port=%d list-queued" % (exe_cmd, api_port) exitcode, out, err = execute(cmd) self.assertEqual(0, exitcode) self.assertTrue(ids[2] in out, 'Image %s was not queued!' % ids[2]) # Delete the image from the queue cmd = ("%s --port=%d --force " "delete-queued-image %s") % (exe_cmd, api_port, ids[2]) exitcode, out, err = execute(cmd) self.assertEqual(0, exitcode) # Verify no queued images cmd = "%s --port=%d list-queued" % (exe_cmd, api_port) exitcode, out, err = execute(cmd) self.assertEqual(0, exitcode) self.assertTrue('No queued images' in out.strip()) # Queue all images for x in xrange(4): cmd = ("%s --port=%d --force " "queue-image %s") % (exe_cmd, api_port, ids[x]) exitcode, out, err = execute(cmd) self.assertEqual(0, exitcode) # Verify queued third image cmd = "%s --port=%d list-queued" % (exe_cmd, api_port) exitcode, out, err = execute(cmd) self.assertEqual(0, exitcode) self.assertTrue('Found 3 queued images' in out) # Delete the image from the queue cmd = ("%s --port=%d --force " "delete-all-queued-images") % (exe_cmd, api_port) exitcode, out, err = execute(cmd) self.assertEqual(0, exitcode) # Verify nothing in queue anymore cmd = "%s --port=%d list-queued" % (exe_cmd, api_port) exitcode, out, err = execute(cmd) self.assertEqual(0, exitcode) self.assertTrue('No queued images' in out.strip()) # verify two image id when queue-image cmd = ("%s --port=%d --force " "queue-image %s %s") % (exe_cmd, api_port, ids[0], ids[1]) exitcode, out, err = execute(cmd, raise_error=False) self.assertEqual(1, exitcode) self.assertTrue('Please specify one and only ID of ' 'the image you wish to ' in out.strip()) # verify two image id when delete-queued-image cmd = ("%s --port=%d --force delete-queued-image " "%s %s") % (exe_cmd, api_port, ids[0], ids[1]) exitcode, out, err = execute(cmd, raise_error=False) self.assertEqual(1, exitcode) self.assertTrue('Please specify one and only ID of ' 'the image you wish to ' in out.strip()) # verify two image id when delete-cached-image cmd = ("%s --port=%d --force delete-cached-image " "%s %s") % (exe_cmd, api_port, ids[0], ids[1]) exitcode, out, err = execute(cmd, raise_error=False) self.assertEqual(1, exitcode) self.assertTrue('Please specify one and only ID of ' 'the image you wish to ' in out.strip()) self.stop_servers() glance-2014.1/glance/tests/functional/db/0000775000175400017540000000000012323736427021323 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/tests/functional/db/test_sqlalchemy.py0000664000175400017540000001146712323736226025104 0ustar jenkinsjenkins00000000000000# Copyright 2012 OpenStack Foundation # Copyright 2013 IBM Corp. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from glance.common import exception import glance.db.sqlalchemy.api from glance.db.sqlalchemy import models as db_models import glance.tests.functional.db as db_tests from glance.tests.functional.db import base def get_db(config): config(connection='sqlite://', group='database') config(verbose=False, debug=False) db_api = glance.db.sqlalchemy.api return db_api def reset_db(db_api): db_models.unregister_models(db_api.get_engine()) db_models.register_models(db_api.get_engine()) class TestSqlAlchemyDriver(base.TestDriver, base.DriverTests): def setUp(self): db_tests.load(get_db, reset_db) super(TestSqlAlchemyDriver, self).setUp() self.addCleanup(db_tests.reset) def test_get_image_with_invalid_long_image_id(self): image_id = '343f9ba5-0197-41be-9543-16bbb32e12aa-xxxxxx' self.assertRaises(exception.NotFound, self.db_api._image_get, self.context, image_id) def test_image_tag_delete_with_invalid_long_image_id(self): image_id = '343f9ba5-0197-41be-9543-16bbb32e12aa-xxxxxx' self.assertRaises(exception.NotFound, self.db_api.image_tag_delete, self.context, image_id, 'fake') def test_image_tag_get_all_with_invalid_long_image_id(self): image_id = '343f9ba5-0197-41be-9543-16bbb32e12aa-xxxxxx' self.assertRaises(exception.NotFound, self.db_api.image_tag_get_all, self.context, image_id) def test_user_get_storage_usage_with_invalid_long_image_id(self): image_id = '343f9ba5-0197-41be-9543-16bbb32e12aa-xxxxxx' self.assertRaises(exception.NotFound, self.db_api.user_get_storage_usage, self.context, 'fake_owner_id', image_id) class TestSqlAlchemyVisibility(base.TestVisibility, base.VisibilityTests): def setUp(self): db_tests.load(get_db, reset_db) super(TestSqlAlchemyVisibility, self).setUp() self.addCleanup(db_tests.reset) class TestSqlAlchemyMembershipVisibility(base.TestMembershipVisibility, base.MembershipVisibilityTests): def setUp(self): db_tests.load(get_db, reset_db) super(TestSqlAlchemyMembershipVisibility, self).setUp() self.addCleanup(db_tests.reset) class TestSqlAlchemyDBDataIntegrity(base.TestDriver): """Test class for checking the data integrity in the database. Helpful in testing scenarios specific to the sqlalchemy api. """ def setUp(self): db_tests.load(get_db, reset_db) super(TestSqlAlchemyDBDataIntegrity, self).setUp() self.addCleanup(db_tests.reset) def test_paginate_redundant_sort_keys(self): original_method = self.db_api._paginate_query def fake_paginate_query(query, model, limit, sort_keys, marker, sort_dir): self.assertEqual(sort_keys, ['created_at', 'id']) return original_method(query, model, limit, sort_keys, marker, sort_dir) self.stubs.Set(self.db_api, '_paginate_query', fake_paginate_query) self.db_api.image_get_all(self.context, sort_key='created_at') def test_paginate_non_redundant_sort_keys(self): original_method = self.db_api._paginate_query def fake_paginate_query(query, model, limit, sort_keys, marker, sort_dir): self.assertEqual(sort_keys, ['name', 'created_at', 'id']) return original_method(query, model, limit, sort_keys, marker, sort_dir) self.stubs.Set(self.db_api, '_paginate_query', fake_paginate_query) self.db_api.image_get_all(self.context, sort_key='name') class TestSqlAlchemyTask(base.TaskTests): def setUp(self): db_tests.load(get_db, reset_db) super(TestSqlAlchemyTask, self).setUp() self.addCleanup(db_tests.reset) class TestSqlAlchemyQuota(base.DriverQuotaTests): def setUp(self): db_tests.load(get_db, reset_db) super(TestSqlAlchemyQuota, self).setUp() self.addCleanup(db_tests.reset) glance-2014.1/glance/tests/functional/db/test_registry.py0000664000175400017540000000522312323736226024603 0ustar jenkinsjenkins00000000000000# Copyright 2013 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. import glance.db from glance.tests import functional import glance.tests.functional.db as db_tests from glance.tests.functional.db import base def get_db(config): config(group='database', connection='sqlite://') config(data_api='glance.db.registry.api') return glance.db.get_api() def reset_db(db_api): pass class FunctionalInitWrapper(functional.FunctionalTest): def setUp(self): # NOTE(flaper87): We need to start the # registry service *before* TestDriver's # setup goes on, since it'll create some # images that will be later used in tests. # # Python's request is way too magical and # it will make the TestDriver's super call # FunctionalTest's without letting us start # the server. # # This setUp will be called by TestDriver # and will be used to call FunctionalTest # setUp method *and* start the registry # service right after it. super(FunctionalInitWrapper, self).setUp() self.registry_server.deployment_flavor = 'fakeauth' self.start_with_retry(self.registry_server, 'registry_port', 3, api_version=2) self.config(registry_port=self.registry_server.bind_port, use_user_token=True) class TestRegistryDriver(base.TestDriver, base.DriverTests, FunctionalInitWrapper): def setUp(self): db_tests.load(get_db, reset_db) super(TestRegistryDriver, self).setUp() self.addCleanup(db_tests.reset) def tearDown(self): self.registry_server.stop() super(TestRegistryDriver, self).tearDown() class TestRegistryQuota(base.DriverQuotaTests, FunctionalInitWrapper): def setUp(self): db_tests.load(get_db, reset_db) super(TestRegistryQuota, self).setUp() self.addCleanup(db_tests.reset) def tearDown(self): self.registry_server.stop() super(TestRegistryQuota, self).tearDown() glance-2014.1/glance/tests/functional/db/test_rpc_endpoint.py0000664000175400017540000000376512323736226025430 0ustar jenkinsjenkins00000000000000# Copyright 2014 Hewlett-Packard Development Company, L.P. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import requests from glance.openstack.common import jsonutils from glance.tests import functional class TestRegistryURLVisibility(functional.FunctionalTest): def setUp(self): super(TestRegistryURLVisibility, self).setUp() self.cleanup() self.registry_server.deployment_flavor = '' self.req_body = jsonutils.dumps([{"command": "image_get_all"}]) def _url(self, path): return 'http://127.0.0.1:%d%s' % (self.registry_port, path) def _headers(self, custom_headers=None): base_headers = { } base_headers.update(custom_headers or {}) return base_headers def test_v2_not_enabled(self): self.registry_server.enable_v2_registry = False self.start_servers(**self.__dict__.copy()) path = self._url('/rpc') response = requests.post(path, headers=self._headers(), data=self.req_body) self.assertEqual(404, response.status_code) self.stop_servers() def test_v2_enabled(self): self.registry_server.enable_v2_registry = True self.start_servers(**self.__dict__.copy()) path = self._url('/rpc') response = requests.post(path, headers=self._headers(), data=self.req_body) self.assertEqual(200, response.status_code) self.stop_servers() glance-2014.1/glance/tests/functional/db/base.py0000664000175400017540000024715112323736226022616 0ustar jenkinsjenkins00000000000000# Copyright 2010-2012 OpenStack Foundation # Copyright 2012 Justin Santa Barbara # Copyright 2013 IBM Corp. # 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 copy import datetime import uuid import mock from glance.common import exception from glance import context from glance.openstack.common import timeutils import glance.tests.functional.db as db_tests from glance.tests import utils as test_utils # The default sort order of results is whatever sort key is specified, # plus created_at and id for ties. When we're not specifying a sort_key, # we get the default (created_at). Some tests below expect the fixtures to be # returned in array-order, so if if the created_at timestamps are the same, # these tests rely on the UUID* values being in order UUID1, UUID2, UUID3 = sorted([str(uuid.uuid4()) for x in range(3)]) def build_image_fixture(**kwargs): default_datetime = timeutils.utcnow() image = { 'id': str(uuid.uuid4()), 'name': 'fake image #2', 'status': 'active', 'disk_format': 'vhd', 'container_format': 'ovf', 'is_public': True, 'created_at': default_datetime, 'updated_at': default_datetime, 'deleted_at': None, 'deleted': False, 'checksum': None, 'min_disk': 5, 'min_ram': 256, 'size': 19, 'locations': [{'url': "file:///tmp/glance-tests/2", 'metadata': {}}], 'properties': {}, } image.update(kwargs) return image def build_task_fixture(**kwargs): default_datetime = timeutils.utcnow() task = { 'id': str(uuid.uuid4()), 'type': 'import', 'status': 'pending', 'input': {'ping': 'pong'}, 'owner': str(uuid.uuid4()), 'message': None, 'expires_at': None, 'created_at': default_datetime, 'updated_at': default_datetime } task.update(kwargs) return task class TestDriver(test_utils.BaseTestCase): def setUp(self): super(TestDriver, self).setUp() context_cls = context.RequestContext self.adm_context = context_cls(is_admin=True, auth_tok='user:user:admin') self.context = context_cls(is_admin=False, auth_tok='user:user:user') self.db_api = db_tests.get_db(self.config) db_tests.reset_db(self.db_api) self.fixtures = self.build_image_fixtures() self.create_images(self.fixtures) def build_image_fixtures(self): dt1 = timeutils.utcnow() dt2 = dt1 + datetime.timedelta(microseconds=5) fixtures = [ { 'id': UUID1, 'created_at': dt1, 'updated_at': dt1, 'properties': {'foo': 'bar', 'far': 'boo'}, 'size': 13, }, { 'id': UUID2, 'created_at': dt1, 'updated_at': dt2, 'size': 17, }, { 'id': UUID3, 'created_at': dt2, 'updated_at': dt2, }, ] return [build_image_fixture(**fixture) for fixture in fixtures] def create_images(self, images): for fixture in images: self.db_api.image_create(self.adm_context, fixture) class DriverTests(object): def test_image_create_requires_status(self): fixture = {'name': 'mark', 'size': 12} self.assertRaises(exception.Invalid, self.db_api.image_create, self.context, fixture) fixture = {'name': 'mark', 'size': 12, 'status': 'queued'} self.db_api.image_create(self.context, fixture) @mock.patch.object(timeutils, 'utcnow') def test_image_create_defaults(self, mock_utcnow): mock_utcnow.return_value = datetime.datetime.utcnow() create_time = timeutils.utcnow() values = {'status': 'queued', 'created_at': create_time, 'updated_at': create_time} image = self.db_api.image_create(self.context, values) self.assertIsNone(image['name']) self.assertIsNone(image['container_format']) self.assertEqual(0, image['min_ram']) self.assertEqual(0, image['min_disk']) self.assertIsNone(image['owner']) self.assertEqual(False, image['is_public']) self.assertIsNone(image['size']) self.assertIsNone(image['checksum']) self.assertIsNone(image['disk_format']) self.assertEqual([], image['locations']) self.assertEqual(False, image['protected']) self.assertEqual(False, image['deleted']) self.assertIsNone(image['deleted_at']) self.assertEqual([], image['properties']) self.assertEqual(image['created_at'], create_time) self.assertEqual(image['updated_at'], create_time) # Image IDs aren't predictable, but they should be populated self.assertTrue(uuid.UUID(image['id'])) #NOTE(bcwaldon): the tags attribute should not be returned as a part # of a core image entity self.assertFalse('tags' in image) def test_image_create_duplicate_id(self): self.assertRaises(exception.Duplicate, self.db_api.image_create, self.context, {'id': UUID1, 'status': 'queued'}) def test_image_create_with_locations(self): locations = [{'url': 'a', 'metadata': {}}, {'url': 'b', 'metadata': {}}] fixture = {'status': 'queued', 'locations': locations} image = self.db_api.image_create(self.context, fixture) actual = [{'url': l['url'], 'metadata': l['metadata']} for l in image['locations']] self.assertEqual(locations, actual) def test_image_create_with_location_data(self): location_data = [{'url': 'a', 'metadata': {'key': 'value'}}, {'url': 'b', 'metadata': {}}] fixture = {'status': 'queued', 'locations': location_data} image = self.db_api.image_create(self.context, fixture) actual = [{'url': l['url'], 'metadata': l['metadata']} for l in image['locations']] self.assertEqual(location_data, actual) def test_image_create_properties(self): fixture = {'status': 'queued', 'properties': {'ping': 'pong'}} image = self.db_api.image_create(self.context, fixture) expected = [{'name': 'ping', 'value': 'pong'}] actual = [{'name': p['name'], 'value': p['value']} for p in image['properties']] self.assertEqual(expected, actual) def test_image_create_unknown_attribtues(self): fixture = {'ping': 'pong'} self.assertRaises(exception.Invalid, self.db_api.image_create, self.context, fixture) def test_image_update_core_attribute(self): fixture = {'status': 'queued'} image = self.db_api.image_update(self.adm_context, UUID3, fixture) self.assertEqual('queued', image['status']) self.assertNotEqual(image['created_at'], image['updated_at']) def test_image_update_with_locations(self): locations = [{'url': 'a', 'metadata': {}}, {'url': 'b', 'metadata': {}}] fixture = {'locations': locations} image = self.db_api.image_update(self.adm_context, UUID3, fixture) self.assertEqual(locations, image['locations']) def test_image_update_with_location_data(self): location_data = [{'url': 'a', 'metadata': {'key': 'value'}}, {'url': 'b', 'metadata': {}}] fixture = {'locations': location_data} image = self.db_api.image_update(self.adm_context, UUID3, fixture) self.assertEqual(location_data, image['locations']) def test_image_update(self): fixture = {'status': 'queued', 'properties': {'ping': 'pong'}} image = self.db_api.image_update(self.adm_context, UUID3, fixture) expected = [{'name': 'ping', 'value': 'pong'}] actual = [{'name': p['name'], 'value': p['value']} for p in image['properties']] self.assertEqual(expected, actual) self.assertEqual('queued', image['status']) self.assertNotEqual(image['created_at'], image['updated_at']) def test_image_update_properties(self): fixture = {'properties': {'ping': 'pong'}} image = self.db_api.image_update(self.adm_context, UUID1, fixture) expected = {'ping': 'pong', 'foo': 'bar', 'far': 'boo'} actual = dict((p['name'], p['value']) for p in image['properties']) self.assertEqual(expected, actual) self.assertNotEqual(image['created_at'], image['updated_at']) def test_image_update_purge_properties(self): fixture = {'properties': {'ping': 'pong'}} image = self.db_api.image_update(self.adm_context, UUID1, fixture, purge_props=True) properties = dict((p['name'], p) for p in image['properties']) # New properties are set self.assertTrue('ping' in properties) self.assertEqual(properties['ping']['value'], 'pong') self.assertEqual(properties['ping']['deleted'], False) # Original properties still show up, but with deleted=True # TODO(markwash): db api should not return deleted properties self.assertTrue('foo' in properties) self.assertEqual(properties['foo']['value'], 'bar') self.assertEqual(properties['foo']['deleted'], True) def test_image_property_delete(self): fixture = {'name': 'ping', 'value': 'pong', 'image_id': UUID1} prop = self.db_api.image_property_create(self.context, fixture) prop = self.db_api.image_property_delete(self.context, prop['name'], UUID1) self.assertIsNotNone(prop['deleted_at']) self.assertTrue(prop['deleted']) def test_image_get(self): image = self.db_api.image_get(self.context, UUID1) self.assertEqual(image['id'], self.fixtures[0]['id']) def test_image_get_disallow_deleted(self): self.db_api.image_destroy(self.adm_context, UUID1) self.assertRaises(exception.NotFound, self.db_api.image_get, self.context, UUID1) def test_image_get_allow_deleted(self): self.db_api.image_destroy(self.adm_context, UUID1) image = self.db_api.image_get(self.adm_context, UUID1) self.assertEqual(image['id'], self.fixtures[0]['id']) self.assertTrue(image['deleted']) def test_image_get_force_allow_deleted(self): self.db_api.image_destroy(self.adm_context, UUID1) image = self.db_api.image_get(self.context, UUID1, force_show_deleted=True) self.assertEqual(image['id'], self.fixtures[0]['id']) def test_image_get_not_owned(self): TENANT1 = str(uuid.uuid4()) TENANT2 = str(uuid.uuid4()) ctxt1 = context.RequestContext(is_admin=False, tenant=TENANT1, auth_tok='user:%s:user' % TENANT1) ctxt2 = context.RequestContext(is_admin=False, tenant=TENANT2, auth_tok='user:%s:user' % TENANT2) image = self.db_api.image_create( ctxt1, {'status': 'queued', 'owner': TENANT1}) self.assertRaises(exception.Forbidden, self.db_api.image_get, ctxt2, image['id']) def test_image_get_not_found(self): UUID = str(uuid.uuid4()) self.assertRaises(exception.NotFound, self.db_api.image_get, self.context, UUID) def test_image_get_all(self): images = self.db_api.image_get_all(self.context) self.assertEqual(3, len(images)) def test_image_get_all_with_filter(self): images = self.db_api.image_get_all(self.context, filters={ 'id': self.fixtures[0]['id'], }) self.assertEqual(len(images), 1) self.assertEqual(images[0]['id'], self.fixtures[0]['id']) def test_image_get_all_with_filter_user_defined_property(self): images = self.db_api.image_get_all(self.context, filters={'foo': 'bar'}) self.assertEqual(len(images), 1) self.assertEqual(images[0]['id'], self.fixtures[0]['id']) def test_image_get_all_with_filter_nonexistent_userdef_property(self): images = self.db_api.image_get_all(self.context, filters={'faz': 'boo'}) self.assertEqual(len(images), 0) def test_image_get_all_with_filter_userdef_prop_nonexistent_value(self): images = self.db_api.image_get_all(self.context, filters={'foo': 'baz'}) self.assertEqual(len(images), 0) def test_image_get_all_with_filter_multiple_user_defined_properties(self): images = self.db_api.image_get_all(self.context, filters={'foo': 'bar', 'far': 'boo'}) self.assertEqual(len(images), 1) self.assertEqual(images[0]['id'], self.fixtures[0]['id']) def test_image_get_all_with_filter_nonexistent_user_defined_property(self): images = self.db_api.image_get_all(self.context, filters={'foo': 'bar', 'faz': 'boo'}) self.assertEqual(len(images), 0) def test_image_get_all_with_filter_user_deleted_property(self): fixture = {'name': 'poo', 'value': 'bear', 'image_id': UUID1} prop = self.db_api.image_property_create(self.context, fixture) images = self.db_api.image_get_all(self.context, filters={ 'properties': {'poo': 'bear'}, }) self.assertEqual(len(images), 1) self.db_api.image_property_delete(self.context, prop['name'], images[0]['id']) images = self.db_api.image_get_all(self.context, filters={ 'properties': {'poo': 'bear'}, }) self.assertEqual(len(images), 0) def test_image_get_all_with_filter_undefined_property(self): images = self.db_api.image_get_all(self.context, filters={'poo': 'bear'}) self.assertEqual(len(images), 0) def test_image_get_all_size_min_max(self): images = self.db_api.image_get_all(self.context, filters={ 'size_min': 10, 'size_max': 15, }) self.assertEqual(len(images), 1) self.assertEqual(images[0]['id'], self.fixtures[0]['id']) def test_image_get_all_size_min(self): images = self.db_api.image_get_all(self.context, filters={'size_min': 15}) self.assertEqual(len(images), 2) self.assertEqual(images[0]['id'], self.fixtures[2]['id']) self.assertEqual(images[1]['id'], self.fixtures[1]['id']) def test_image_get_all_size_range(self): images = self.db_api.image_get_all(self.context, filters={'size_max': 15, 'size_min': 20}) self.assertEqual(len(images), 0) def test_image_get_all_size_max(self): images = self.db_api.image_get_all(self.context, filters={'size_max': 15}) self.assertEqual(len(images), 1) self.assertEqual(images[0]['id'], self.fixtures[0]['id']) def test_image_get_all_with_filter_min_range_bad_value(self): self.assertRaises(exception.InvalidFilterRangeValue, self.db_api.image_get_all, self.context, filters={'size_min': 'blah'}) def test_image_get_all_with_filter_max_range_bad_value(self): self.assertRaises(exception.InvalidFilterRangeValue, self.db_api.image_get_all, self.context, filters={'size_max': 'blah'}) def test_image_get_all_marker(self): images = self.db_api.image_get_all(self.context, marker=UUID3) self.assertEqual(2, len(images)) def test_image_get_all_marker_deleted(self): """Cannot specify a deleted image as a marker.""" self.db_api.image_destroy(self.adm_context, UUID1) filters = {'deleted': False} self.assertRaises(exception.NotFound, self.db_api.image_get_all, self.context, marker=UUID1, filters=filters) def test_image_get_all_marker_deleted_showing_deleted_as_admin(self): """Specify a deleted image as a marker if showing deleted images.""" self.db_api.image_destroy(self.adm_context, UUID3) images = self.db_api.image_get_all(self.adm_context, marker=UUID3) #NOTE(bcwaldon): an admin should see all images (deleted or not) self.assertEqual(2, len(images)) def test_image_get_all_marker_deleted_showing_deleted(self): """Specify a deleted image as a marker if showing deleted images. A non-admin user has to explicitly ask for deleted images, and should only see deleted images in the results """ self.db_api.image_destroy(self.adm_context, UUID3) self.db_api.image_destroy(self.adm_context, UUID1) filters = {'deleted': True} images = self.db_api.image_get_all(self.context, marker=UUID3, filters=filters) self.assertEqual(1, len(images)) def test_image_get_all_marker_null_name_desc(self): """Check an image with name null is handled Check an image with name null is handled marker is specified and order is descending """ TENANT1 = str(uuid.uuid4()) ctxt1 = context.RequestContext(is_admin=False, tenant=TENANT1, auth_tok='user:%s:user' % TENANT1) UUIDX = str(uuid.uuid4()) self.db_api.image_create(ctxt1, {'id': UUIDX, 'status': 'queued', 'name': None, 'owner': TENANT1}) images = self.db_api.image_get_all(ctxt1, marker=UUIDX, sort_key='name', sort_dir='desc') image_ids = [image['id'] for image in images] expected = [] self.assertEqual(sorted(expected), sorted(image_ids)) def test_image_get_all_marker_null_disk_format_desc(self): """Check an image with disk_format null is handled Check an image with disk_format null is handled when marker is specified and order is descending """ TENANT1 = str(uuid.uuid4()) ctxt1 = context.RequestContext(is_admin=False, tenant=TENANT1, auth_tok='user:%s:user' % TENANT1) UUIDX = str(uuid.uuid4()) self.db_api.image_create(ctxt1, {'id': UUIDX, 'status': 'queued', 'disk_format': None, 'owner': TENANT1}) images = self.db_api.image_get_all(ctxt1, marker=UUIDX, sort_key='disk_format', sort_dir='desc') image_ids = [image['id'] for image in images] expected = [] self.assertEqual(sorted(expected), sorted(image_ids)) def test_image_get_all_marker_null_container_format_desc(self): """Check an image with container_format null is handled Check an image with container_format null is handled when marker is specified and order is descending """ TENANT1 = str(uuid.uuid4()) ctxt1 = context.RequestContext(is_admin=False, tenant=TENANT1, auth_tok='user:%s:user' % TENANT1) UUIDX = str(uuid.uuid4()) self.db_api.image_create(ctxt1, {'id': UUIDX, 'status': 'queued', 'container_format': None, 'owner': TENANT1}) images = self.db_api.image_get_all(ctxt1, marker=UUIDX, sort_key='container_format', sort_dir='desc') image_ids = [image['id'] for image in images] expected = [] self.assertEqual(sorted(expected), sorted(image_ids)) def test_image_get_all_marker_null_name_asc(self): """Check an image with name null is handled Check an image with name null is handled when marker is specified and order is ascending """ TENANT1 = str(uuid.uuid4()) ctxt1 = context.RequestContext(is_admin=False, tenant=TENANT1, auth_tok='user:%s:user' % TENANT1) UUIDX = str(uuid.uuid4()) self.db_api.image_create(ctxt1, {'id': UUIDX, 'status': 'queued', 'name': None, 'owner': TENANT1}) images = self.db_api.image_get_all(ctxt1, marker=UUIDX, sort_key='name', sort_dir='asc') image_ids = [image['id'] for image in images] expected = [UUID3, UUID2, UUID1] self.assertEqual(sorted(expected), sorted(image_ids)) def test_image_get_all_marker_null_disk_format_asc(self): """Check an image with disk_format null is handled Check an image with disk_format null is handled when marker is specified and order is ascending """ TENANT1 = str(uuid.uuid4()) ctxt1 = context.RequestContext(is_admin=False, tenant=TENANT1, auth_tok='user:%s:user' % TENANT1) UUIDX = str(uuid.uuid4()) self.db_api.image_create(ctxt1, {'id': UUIDX, 'status': 'queued', 'disk_format': None, 'owner': TENANT1}) images = self.db_api.image_get_all(ctxt1, marker=UUIDX, sort_key='disk_format', sort_dir='asc') image_ids = [image['id'] for image in images] expected = [UUID3, UUID2, UUID1] self.assertEqual(sorted(expected), sorted(image_ids)) def test_image_get_all_marker_null_container_format_asc(self): """Check an image with container_format null is handled Check an image with container_format null is handled when marker is specified and order is ascending """ TENANT1 = str(uuid.uuid4()) ctxt1 = context.RequestContext(is_admin=False, tenant=TENANT1, auth_tok='user:%s:user' % TENANT1) UUIDX = str(uuid.uuid4()) self.db_api.image_create(ctxt1, {'id': UUIDX, 'status': 'queued', 'container_format': None, 'owner': TENANT1}) images = self.db_api.image_get_all(ctxt1, marker=UUIDX, sort_key='container_format', sort_dir='asc') image_ids = [image['id'] for image in images] expected = [UUID3, UUID2, UUID1] self.assertEqual(sorted(expected), sorted(image_ids)) def test_image_get_all_limit(self): images = self.db_api.image_get_all(self.context, limit=2) self.assertEqual(2, len(images)) # A limit of None should not equate to zero images = self.db_api.image_get_all(self.context, limit=None) self.assertEqual(3, len(images)) # A limit of zero should actually mean zero images = self.db_api.image_get_all(self.context, limit=0) self.assertEqual(0, len(images)) def test_image_get_all_owned(self): TENANT1 = str(uuid.uuid4()) ctxt1 = context.RequestContext(is_admin=False, tenant=TENANT1, auth_tok='user:%s:user' % TENANT1) UUIDX = str(uuid.uuid4()) image_meta_data = {'id': UUIDX, 'status': 'queued', 'owner': TENANT1} self.db_api.image_create(ctxt1, image_meta_data) TENANT2 = str(uuid.uuid4()) ctxt2 = context.RequestContext(is_admin=False, tenant=TENANT2, auth_tok='user:%s:user' % TENANT2) UUIDY = str(uuid.uuid4()) image_meta_data = {'id': UUIDY, 'status': 'queued', 'owner': TENANT2} self.db_api.image_create(ctxt2, image_meta_data) images = self.db_api.image_get_all(ctxt1) image_ids = [image['id'] for image in images] expected = [UUIDX, UUID3, UUID2, UUID1] self.assertEqual(sorted(expected), sorted(image_ids)) def test_image_get_all_owned_checksum(self): TENANT1 = str(uuid.uuid4()) ctxt1 = context.RequestContext(is_admin=False, tenant=TENANT1, auth_tok='user:%s:user' % TENANT1) UUIDX = str(uuid.uuid4()) CHECKSUM1 = '91264c3edf5972c9f1cb309543d38a5c' image_meta_data = { 'id': UUIDX, 'status': 'queued', 'checksum': CHECKSUM1, 'owner': TENANT1 } self.db_api.image_create(ctxt1, image_meta_data) image_member_data = { 'image_id': UUIDX, 'member': TENANT1, 'can_share': False, "status": "accepted", } self.db_api.image_member_create(ctxt1, image_member_data) TENANT2 = str(uuid.uuid4()) ctxt2 = context.RequestContext(is_admin=False, tenant=TENANT2, auth_tok='user:%s:user' % TENANT2) UUIDY = str(uuid.uuid4()) CHECKSUM2 = '92264c3edf5972c9f1cb309543d38a5c' image_meta_data = { 'id': UUIDY, 'status': 'queued', 'checksum': CHECKSUM2, 'owner': TENANT2 } self.db_api.image_create(ctxt2, image_meta_data) image_member_data = { 'image_id': UUIDY, 'member': TENANT2, 'can_share': False, "status": "accepted", } self.db_api.image_member_create(ctxt2, image_member_data) filters = {'visibility': 'shared', 'checksum': CHECKSUM2} images = self.db_api.image_get_all(ctxt2, filters) self.assertEqual(1, len(images)) self.assertEqual(UUIDY, images[0]['id']) def test_image_get_all_with_filter_tags(self): self.db_api.image_tag_create(self.context, UUID1, 'x86') self.db_api.image_tag_create(self.context, UUID1, '64bit') self.db_api.image_tag_create(self.context, UUID2, 'power') self.db_api.image_tag_create(self.context, UUID2, '64bit') images = self.db_api.image_get_all(self.context, filters={'tags': ['64bit']}) self.assertEqual(len(images), 2) image_ids = [image['id'] for image in images] expected = [UUID1, UUID2] self.assertEqual(sorted(expected), sorted(image_ids)) def test_image_get_all_with_filter_multi_tags(self): self.db_api.image_tag_create(self.context, UUID1, 'x86') self.db_api.image_tag_create(self.context, UUID1, '64bit') self.db_api.image_tag_create(self.context, UUID2, 'power') self.db_api.image_tag_create(self.context, UUID2, '64bit') images = self.db_api.image_get_all(self.context, filters={'tags': ['64bit', 'power'] }) self.assertEqual(len(images), 1) self.assertEqual(UUID2, images[0]['id']) def test_image_get_all_with_filter_tags_and_nonexistent(self): self.db_api.image_tag_create(self.context, UUID1, 'x86') images = self.db_api.image_get_all(self.context, filters={'tags': ['x86', 'fake'] }) self.assertEqual(len(images), 0) def test_image_get_all_with_filter_deleted_tags(self): tag = self.db_api.image_tag_create(self.context, UUID1, 'AIX') images = self.db_api.image_get_all(self.context, filters={ 'tags': [tag], }) self.assertEqual(len(images), 1) self.db_api.image_tag_delete(self.context, UUID1, tag) images = self.db_api.image_get_all(self.context, filters={ 'tags': [tag], }) self.assertEqual(len(images), 0) def test_image_get_all_with_filter_undefined_tags(self): images = self.db_api.image_get_all(self.context, filters={'tags': ['fake']}) self.assertEqual(len(images), 0) def test_image_paginate(self): """Paginate through a list of images using limit and marker""" extra_uuids = [str(uuid.uuid4()) for i in range(2)] extra_images = [build_image_fixture(id=_id) for _id in extra_uuids] self.create_images(extra_images) # Reverse uuids to match default sort of created_at extra_uuids.reverse() page = self.db_api.image_get_all(self.context, limit=2) self.assertEqual(extra_uuids, [i['id'] for i in page]) last = page[-1]['id'] page = self.db_api.image_get_all(self.context, limit=2, marker=last) self.assertEqual([UUID3, UUID2], [i['id'] for i in page]) page = self.db_api.image_get_all(self.context, limit=2, marker=UUID2) self.assertEqual([UUID1], [i['id'] for i in page]) def test_image_get_all_invalid_sort_key(self): self.assertRaises(exception.InvalidSortKey, self.db_api.image_get_all, self.context, sort_key='blah') def test_image_get_all_limit_marker(self): images = self.db_api.image_get_all(self.context, limit=2) self.assertEqual(2, len(images)) def test_image_destroy(self): location_data = [{'url': 'a', 'metadata': {'key': 'value'}}, {'url': 'b', 'metadata': {}}] fixture = {'status': 'queued', 'locations': location_data} image = self.db_api.image_create(self.context, fixture) IMG_ID = image['id'] fixture = {'name': 'ping', 'value': 'pong', 'image_id': IMG_ID} prop = self.db_api.image_property_create(self.context, fixture) TENANT2 = str(uuid.uuid4()) fixture = {'image_id': IMG_ID, 'member': TENANT2, 'can_share': False} member = self.db_api.image_member_create(self.context, fixture) self.db_api.image_tag_create(self.context, IMG_ID, 'snarf') self.assertEqual(location_data, image['locations']) self.assertEqual(('ping', 'pong', IMG_ID, False), (prop['name'], prop['value'], prop['image_id'], prop['deleted'])) self.assertEqual((TENANT2, IMG_ID, False), (member['member'], member['image_id'], member['can_share'])) self.assertEqual(['snarf'], self.db_api.image_tag_get_all(self.context, IMG_ID)) image = self.db_api.image_destroy(self.adm_context, IMG_ID) self.assertTrue(image['deleted']) self.assertTrue(image['deleted_at']) self.assertRaises(exception.NotFound, self.db_api.image_get, self.context, IMG_ID) self.assertEqual([], image['locations']) prop = image['properties'][0] self.assertEqual(('ping', IMG_ID, True), (prop['name'], prop['image_id'], prop['deleted'])) self.context.auth_tok = 'user:%s:user' % TENANT2 members = self.db_api.image_member_find(self.context, IMG_ID) self.assertEqual([], members) tags = self.db_api.image_tag_get_all(self.context, IMG_ID) self.assertEqual([], tags) def test_image_destroy_with_delete_all(self): """Check the image child element's _image_delete_all methods. checks if all the image_delete_all methods deletes only the child elements of the image to be deleted. """ TENANT2 = str(uuid.uuid4()) location_data = [{'url': 'a', 'metadata': {'key': 'value'}}, {'url': 'b', 'metadata': {}}] def _create_image_with_child_entries(): fixture = {'status': 'queued', 'locations': location_data} image_id = self.db_api.image_create(self.context, fixture)['id'] fixture = {'name': 'ping', 'value': 'pong', 'image_id': image_id} self.db_api.image_property_create(self.context, fixture) fixture = {'image_id': image_id, 'member': TENANT2, 'can_share': False} self.db_api.image_member_create(self.context, fixture) self.db_api.image_tag_create(self.context, image_id, 'snarf') return image_id ACTIVE_IMG_ID = _create_image_with_child_entries() DEL_IMG_ID = _create_image_with_child_entries() deleted_image = self.db_api.image_destroy(self.adm_context, DEL_IMG_ID) self.assertTrue(deleted_image['deleted']) self.assertTrue(deleted_image['deleted_at']) self.assertRaises(exception.NotFound, self.db_api.image_get, self.context, DEL_IMG_ID) active_image = self.db_api.image_get(self.context, ACTIVE_IMG_ID) self.assertFalse(active_image['deleted']) self.assertFalse(active_image['deleted_at']) self.assertEqual(location_data, active_image['locations']) self.assertEqual(1, len(active_image['properties'])) prop = active_image['properties'][0] self.assertEqual(('ping', 'pong', ACTIVE_IMG_ID), (prop['name'], prop['value'], prop['image_id'])) self.assertEqual((False, None), (prop['deleted'], prop['deleted_at'])) self.context.auth_tok = 'user:%s:user' % TENANT2 members = self.db_api.image_member_find(self.context, ACTIVE_IMG_ID) self.assertEqual(1, len(members)) member = members[0] self.assertEqual((TENANT2, ACTIVE_IMG_ID, False), (member['member'], member['image_id'], member['can_share'])) tags = self.db_api.image_tag_get_all(self.context, ACTIVE_IMG_ID) self.assertEqual(['snarf'], tags) def test_image_get_multiple_members(self): TENANT1 = str(uuid.uuid4()) TENANT2 = str(uuid.uuid4()) ctxt1 = context.RequestContext(is_admin=False, tenant=TENANT1, auth_tok='user:%s:user' % TENANT1, owner_is_tenant=True) ctxt2 = context.RequestContext(is_admin=False, user=TENANT2, auth_tok='user:%s:user' % TENANT2, owner_is_tenant=False) UUIDX = str(uuid.uuid4()) #we need private image and context.owner should not match image owner self.db_api.image_create(ctxt1, {'id': UUIDX, 'status': 'queued', 'is_public': False, 'owner': TENANT1}) values = {'image_id': UUIDX, 'member': TENANT2, 'can_share': False} self.db_api.image_member_create(ctxt1, values) image = self.db_api.image_get(ctxt2, UUIDX) self.assertEqual(UUIDX, image['id']) # by default get_all displays only images with status 'accepted' images = self.db_api.image_get_all(ctxt2) self.assertEqual(3, len(images)) # filter by rejected images = self.db_api.image_get_all(ctxt2, member_status='rejected') self.assertEqual(3, len(images)) # filter by visibility images = self.db_api.image_get_all(ctxt2, filters={'visibility': 'shared'}) self.assertEqual(0, len(images)) # filter by visibility images = self.db_api.image_get_all(ctxt2, member_status='pending', filters={'visibility': 'shared'}) self.assertEqual(1, len(images)) # filter by visibility images = self.db_api.image_get_all(ctxt2, member_status='all', filters={'visibility': 'shared'}) self.assertEqual(1, len(images)) # filter by status pending images = self.db_api.image_get_all(ctxt2, member_status='pending') self.assertEqual(4, len(images)) # filter by status all images = self.db_api.image_get_all(ctxt2, member_status='all') self.assertEqual(4, len(images)) def test_is_image_visible(self): TENANT1 = str(uuid.uuid4()) TENANT2 = str(uuid.uuid4()) ctxt1 = context.RequestContext(is_admin=False, tenant=TENANT1, auth_tok='user:%s:user' % TENANT1, owner_is_tenant=True) ctxt2 = context.RequestContext(is_admin=False, user=TENANT2, auth_tok='user:%s:user' % TENANT2, owner_is_tenant=False) UUIDX = str(uuid.uuid4()) #we need private image and context.owner should not match image owner image = self.db_api.image_create(ctxt1, {'id': UUIDX, 'status': 'queued', 'is_public': False, 'owner': TENANT1}) values = {'image_id': UUIDX, 'member': TENANT2, 'can_share': False} self.db_api.image_member_create(ctxt1, values) result = self.db_api.is_image_visible(ctxt2, image) self.assertTrue(result) # image should not be visible for a deleted member members = self.db_api.image_member_find(ctxt1, image_id=UUIDX) self.db_api.image_member_delete(ctxt1, members[0]['id']) result = self.db_api.is_image_visible(ctxt2, image) self.assertFalse(result) def test_image_tag_create(self): tag = self.db_api.image_tag_create(self.context, UUID1, 'snap') self.assertEqual('snap', tag) def test_image_tag_set_all(self): tags = self.db_api.image_tag_get_all(self.context, UUID1) self.assertEqual([], tags) self.db_api.image_tag_set_all(self.context, UUID1, ['ping', 'pong']) tags = self.db_api.image_tag_get_all(self.context, UUID1) #NOTE(bcwaldon): tag ordering should match exactly what was provided self.assertEqual(['ping', 'pong'], tags) def test_image_tag_get_all(self): self.db_api.image_tag_create(self.context, UUID1, 'snap') self.db_api.image_tag_create(self.context, UUID1, 'snarf') self.db_api.image_tag_create(self.context, UUID2, 'snarf') # Check the tags for the first image tags = self.db_api.image_tag_get_all(self.context, UUID1) expected = ['snap', 'snarf'] self.assertEqual(expected, tags) # Check the tags for the second image tags = self.db_api.image_tag_get_all(self.context, UUID2) expected = ['snarf'] self.assertEqual(expected, tags) def test_image_tag_get_all_no_tags(self): actual = self.db_api.image_tag_get_all(self.context, UUID1) self.assertEqual([], actual) def test_image_tag_get_all_non_existent_image(self): bad_image_id = str(uuid.uuid4()) actual = self.db_api.image_tag_get_all(self.context, bad_image_id) self.assertEqual([], actual) def test_image_tag_delete(self): self.db_api.image_tag_create(self.context, UUID1, 'snap') self.db_api.image_tag_delete(self.context, UUID1, 'snap') self.assertRaises(exception.NotFound, self.db_api.image_tag_delete, self.context, UUID1, 'snap') @mock.patch.object(timeutils, 'utcnow') def test_image_member_create(self, mock_utcnow): mock_utcnow.return_value = datetime.datetime.utcnow() memberships = self.db_api.image_member_find(self.context) self.assertEqual([], memberships) TENANT1 = str(uuid.uuid4()) # NOTE(flaper87): Update auth token, otherwise # non visible members won't be returned. self.context.auth_tok = 'user:%s:user' % TENANT1 self.db_api.image_member_create(self.context, {'member': TENANT1, 'image_id': UUID1}) memberships = self.db_api.image_member_find(self.context) self.assertEqual(1, len(memberships)) actual = memberships[0] self.assertIsNotNone(actual['created_at']) self.assertIsNotNone(actual['updated_at']) actual.pop('id') actual.pop('created_at') actual.pop('updated_at') expected = { 'member': TENANT1, 'image_id': UUID1, 'can_share': False, 'status': 'pending', } self.assertEqual(expected, actual) def test_image_member_update(self): TENANT1 = str(uuid.uuid4()) # NOTE(flaper87): Update auth token, otherwise # non visible members won't be returned. self.context.auth_tok = 'user:%s:user' % TENANT1 member = self.db_api.image_member_create(self.context, {'member': TENANT1, 'image_id': UUID1}) member_id = member.pop('id') member.pop('created_at') member.pop('updated_at') expected = {'member': TENANT1, 'image_id': UUID1, 'status': 'pending', 'can_share': False} self.assertEqual(expected, member) member = self.db_api.image_member_update(self.context, member_id, {'can_share': True}) self.assertNotEqual(member['created_at'], member['updated_at']) member.pop('id') member.pop('created_at') member.pop('updated_at') expected = {'member': TENANT1, 'image_id': UUID1, 'status': 'pending', 'can_share': True} self.assertEqual(expected, member) members = self.db_api.image_member_find(self.context, member=TENANT1, image_id=UUID1) member = members[0] member.pop('id') member.pop('created_at') member.pop('updated_at') self.assertEqual(expected, member) def test_image_member_update_status(self): TENANT1 = str(uuid.uuid4()) # NOTE(flaper87): Update auth token, otherwise # non visible members won't be returned. self.context.auth_tok = 'user:%s:user' % TENANT1 member = self.db_api.image_member_create(self.context, {'member': TENANT1, 'image_id': UUID1}) member_id = member.pop('id') member.pop('created_at') member.pop('updated_at') expected = {'member': TENANT1, 'image_id': UUID1, 'status': 'pending', 'can_share': False} self.assertEqual(expected, member) member = self.db_api.image_member_update(self.context, member_id, {'status': 'accepted'}) self.assertNotEqual(member['created_at'], member['updated_at']) member.pop('id') member.pop('created_at') member.pop('updated_at') expected = {'member': TENANT1, 'image_id': UUID1, 'status': 'accepted', 'can_share': False} self.assertEqual(expected, member) members = self.db_api.image_member_find(self.context, member=TENANT1, image_id=UUID1) member = members[0] member.pop('id') member.pop('created_at') member.pop('updated_at') self.assertEqual(expected, member) def test_image_member_find(self): TENANT1 = str(uuid.uuid4()) TENANT2 = str(uuid.uuid4()) fixtures = [ {'member': TENANT1, 'image_id': UUID1}, {'member': TENANT1, 'image_id': UUID2, 'status': 'rejected'}, {'member': TENANT2, 'image_id': UUID1, 'status': 'accepted'}, ] for f in fixtures: self.db_api.image_member_create(self.context, copy.deepcopy(f)) def _simplify(output): return def _assertMemberListMatch(list1, list2): _simple = lambda x: set([(o['member'], o['image_id']) for o in x]) self.assertEqual(_simple(list1), _simple(list2)) # NOTE(flaper87): Update auth token, otherwise # non visible members won't be returned. self.context.auth_tok = 'user:%s:user' % TENANT1 output = self.db_api.image_member_find(self.context, member=TENANT1) _assertMemberListMatch([fixtures[0], fixtures[1]], output) output = self.db_api.image_member_find(self.adm_context, image_id=UUID1) _assertMemberListMatch([fixtures[0], fixtures[2]], output) # NOTE(flaper87): Update auth token, otherwise # non visible members won't be returned. self.context.auth_tok = 'user:%s:user' % TENANT2 output = self.db_api.image_member_find(self.context, member=TENANT2, image_id=UUID1) _assertMemberListMatch([fixtures[2]], output) output = self.db_api.image_member_find(self.context, status='accepted') _assertMemberListMatch([fixtures[2]], output) # NOTE(flaper87): Update auth token, otherwise # non visible members won't be returned. self.context.auth_tok = 'user:%s:user' % TENANT1 output = self.db_api.image_member_find(self.context, status='rejected') _assertMemberListMatch([fixtures[1]], output) output = self.db_api.image_member_find(self.context, status='pending') _assertMemberListMatch([fixtures[0]], output) output = self.db_api.image_member_find(self.context, status='pending', image_id=UUID2) _assertMemberListMatch([], output) image_id = str(uuid.uuid4()) output = self.db_api.image_member_find(self.context, member=TENANT2, image_id=image_id) _assertMemberListMatch([], output) def test_image_member_count(self): TENANT1 = str(uuid.uuid4()) self.db_api.image_member_create(self.context, {'member': TENANT1, 'image_id': UUID1}) actual = self.db_api.image_member_count(self.context, UUID1) self.assertEqual(actual, 1) def test_image_member_count_invalid_image_id(self): TENANT1 = str(uuid.uuid4()) self.db_api.image_member_create(self.context, {'member': TENANT1, 'image_id': UUID1}) self.assertRaises(exception.Invalid, self.db_api.image_member_count, self.context, None) def test_image_member_count_empty_image_id(self): TENANT1 = str(uuid.uuid4()) self.db_api.image_member_create(self.context, {'member': TENANT1, 'image_id': UUID1}) self.assertRaises(exception.Invalid, self.db_api.image_member_count, self.context, "") def test_image_member_delete(self): TENANT1 = str(uuid.uuid4()) # NOTE(flaper87): Update auth token, otherwise # non visible members won't be returned. self.context.auth_tok = 'user:%s:user' % TENANT1 fixture = {'member': TENANT1, 'image_id': UUID1, 'can_share': True} member = self.db_api.image_member_create(self.context, fixture) self.assertEqual(1, len(self.db_api.image_member_find(self.context))) member = self.db_api.image_member_delete(self.context, member['id']) self.assertEqual(0, len(self.db_api.image_member_find(self.context))) class DriverQuotaTests(test_utils.BaseTestCase): def setUp(self): super(DriverQuotaTests, self).setUp() self.owner_id1 = str(uuid.uuid4()) self.context1 = context.RequestContext( is_admin=False, user=self.owner_id1, tenant=self.owner_id1, auth_tok='%s:%s:user' % (self.owner_id1, self.owner_id1)) self.db_api = db_tests.get_db(self.config) db_tests.reset_db(self.db_api) dt1 = timeutils.utcnow() dt2 = dt1 + datetime.timedelta(microseconds=5) fixtures = [ { 'id': UUID1, 'created_at': dt1, 'updated_at': dt1, 'size': 13, 'owner': self.owner_id1, }, { 'id': UUID2, 'created_at': dt1, 'updated_at': dt2, 'size': 17, 'owner': self.owner_id1, }, { 'id': UUID3, 'created_at': dt2, 'updated_at': dt2, 'size': 7, 'owner': self.owner_id1, }, ] self.owner1_fixtures = [ build_image_fixture(**fixture) for fixture in fixtures] for fixture in self.owner1_fixtures: self.db_api.image_create(self.context1, fixture) def test_storage_quota(self): total = reduce(lambda x, y: x + y, [f['size'] for f in self.owner1_fixtures]) x = self.db_api.user_get_storage_usage(self.context1, self.owner_id1) self.assertEqual(total, x) def test_storage_quota_without_image_id(self): total = reduce(lambda x, y: x + y, [f['size'] for f in self.owner1_fixtures]) total = total - self.owner1_fixtures[0]['size'] x = self.db_api.user_get_storage_usage( self.context1, self.owner_id1, image_id=self.owner1_fixtures[0]['id']) self.assertEqual(total, x) def test_storage_quota_multiple_locations(self): dt1 = timeutils.utcnow() sz = 53 new_fixture_dict = {'id': str(uuid.uuid4()), 'created_at': dt1, 'updated_at': dt1, 'size': sz, 'owner': self.owner_id1} new_fixture = build_image_fixture(**new_fixture_dict) new_fixture['locations'].append({'url': 'file:///some/path/file', 'metadata': {}}) self.db_api.image_create(self.context1, new_fixture) total = reduce(lambda x, y: x + y, [f['size'] for f in self.owner1_fixtures]) + (sz * 2) x = self.db_api.user_get_storage_usage(self.context1, self.owner_id1) self.assertEqual(total, x) def test_storage_quota_deleted_image(self): # NOTE(flaper87): This needs to be tested for # soft deleted images as well. Currently there's no # good way to delete locations. dt1 = timeutils.utcnow() sz = 53 image_id = str(uuid.uuid4()) new_fixture_dict = {'id': image_id, 'created_at': dt1, 'updated_at': dt1, 'size': sz, 'owner': self.owner_id1} new_fixture = build_image_fixture(**new_fixture_dict) new_fixture['locations'].append({'url': 'file:///some/path/file', 'metadata': {}}) self.db_api.image_create(self.context1, new_fixture) total = reduce(lambda x, y: x + y, [f['size'] for f in self.owner1_fixtures]) x = self.db_api.user_get_storage_usage(self.context1, self.owner_id1) self.assertEqual(total + (sz * 2), x) self.db_api.image_destroy(self.context1, image_id) x = self.db_api.user_get_storage_usage(self.context1, self.owner_id1) self.assertEqual(total, x) class TaskTests(test_utils.BaseTestCase): def setUp(self): super(TaskTests, self).setUp() self.owner_id1 = str(uuid.uuid4()) self.adm_context = context.RequestContext(is_admin=True, auth_tok='user:user:admin') self.context = context.RequestContext( is_admin=False, auth_tok='user:user:user', user=self.owner_id1) self.db_api = db_tests.get_db(self.config) self.fixtures = self.build_task_fixtures() db_tests.reset_db(self.db_api) def build_task_fixtures(self): self.context.tenant = str(uuid.uuid4()) fixtures = [ { 'owner': self.context.owner, 'type': 'import', 'input': {'import_from': 'file:///a.img', 'import_from_format': 'qcow2', 'image_properties': { "name": "GreatStack 1.22", "tags": ["lamp", "custom"] }}, }, { 'owner': self.context.owner, 'type': 'import', 'input': {'import_from': 'file:///b.img', 'import_from_format': 'qcow2', 'image_properties': { "name": "GreatStack 1.23", "tags": ["lamp", "good"] }}, }, { 'owner': self.context.owner, "type": "export", "input": { "export_uuid": "deadbeef-dead-dead-dead-beefbeefbeef", "export_to": "swift://cloud.foo/myaccount/mycontainer/path", "export_format": "qcow2" } }, ] return [build_task_fixture(**fixture) for fixture in fixtures] def test_task_get_all_with_filter(self): for fixture in self.fixtures: self.db_api.task_create(self.context, build_task_fixture(**fixture)) import_tasks = self.db_api.task_get_all(self.context, filters={'type': 'import'}) self.assertTrue(import_tasks) self.assertEqual(len(import_tasks), 2) for task in import_tasks: self.assertEqual(task['type'], 'import') self.assertEqual(task['owner'], self.context.owner) def test_task_get_all_as_admin(self): tasks = [] for fixture in self.fixtures: task = self.db_api.task_create(self.context, build_task_fixture(**fixture)) tasks.append(task) import_tasks = self.db_api.task_get_all(self.adm_context) self.assertTrue(import_tasks) self.assertEqual(len(import_tasks), 3) def test_task_get_all_marker(self): for fixture in self.fixtures: self.db_api.task_create(self.context, build_task_fixture(**fixture)) tasks = self.db_api.task_get_all(self.context, sort_key='id') task_ids = [t['id'] for t in tasks] tasks = self.db_api.task_get_all(self.context, sort_key='id', marker=task_ids[0]) self.assertEqual(len(tasks), 2) def test_task_get_all_limit(self): for fixture in self.fixtures: self.db_api.task_create(self.context, build_task_fixture(**fixture)) tasks = self.db_api.task_get_all(self.context, limit=2) self.assertEqual(2, len(tasks)) # A limit of None should not equate to zero tasks = self.db_api.task_get_all(self.context, limit=None) self.assertEqual(3, len(tasks)) # A limit of zero should actually mean zero tasks = self.db_api.task_get_all(self.context, limit=0) self.assertEqual(0, len(tasks)) def test_task_get_all_owned(self): TENANT1 = str(uuid.uuid4()) ctxt1 = context.RequestContext(is_admin=False, tenant=TENANT1, auth_tok='user:%s:user' % TENANT1) task_values = {'type': 'import', 'status': 'pending', 'input': '{"loc": "fake"}', 'owner': TENANT1} self.db_api.task_create(ctxt1, task_values) TENANT2 = str(uuid.uuid4()) ctxt2 = context.RequestContext(is_admin=False, tenant=TENANT2, auth_tok='user:%s:user' % TENANT2) task_values = {'type': 'export', 'status': 'pending', 'input': '{"loc": "fake"}', 'owner': TENANT2} self.db_api.task_create(ctxt2, task_values) tasks = self.db_api.task_get_all(ctxt1) task_owners = set([task['owner'] for task in tasks]) expected = set([TENANT1]) self.assertEqual(sorted(expected), sorted(task_owners)) def test_task_get(self): expires_at = timeutils.utcnow() image_id = str(uuid.uuid4()) fixture = { 'owner': self.context.owner, 'type': 'import', 'status': 'pending', 'input': '{"loc": "fake"}', 'result': "{'image_id': %s}" % image_id, 'message': 'blah', 'expires_at': expires_at } task = self.db_api.task_create(self.context, fixture) self.assertIsNotNone(task) self.assertIsNotNone(task['id']) task_id = task['id'] task = self.db_api.task_get(self.context, task_id) self.assertIsNotNone(task) self.assertEqual(task['id'], task_id) self.assertEqual(task['owner'], self.context.owner) self.assertEqual(task['type'], 'import') self.assertEqual(task['status'], 'pending') self.assertEqual(task['input'], fixture['input']) self.assertEqual(task['result'], fixture['result']) self.assertEqual(task['message'], fixture['message']) self.assertEqual(task['expires_at'], expires_at) def test_task_get_all(self): now = timeutils.utcnow() image_id = str(uuid.uuid4()) fixture1 = { 'owner': self.context.owner, 'type': 'import', 'status': 'pending', 'input': '{"loc": "fake_1"}', 'result': "{'image_id': %s}" % image_id, 'message': 'blah_1', 'expires_at': now, 'created_at': now, 'updated_at': now } fixture2 = { 'owner': self.context.owner, 'type': 'import', 'status': 'pending', 'input': '{"loc": "fake_2"}', 'result': "{'image_id': %s}" % image_id, 'message': 'blah_2', 'expires_at': now, 'created_at': now, 'updated_at': now } task1 = self.db_api.task_create(self.context, fixture1) task2 = self.db_api.task_create(self.context, fixture2) self.assertIsNotNone(task1) self.assertIsNotNone(task2) task1_id = task1['id'] task2_id = task2['id'] task_fixtures = {task1_id: fixture1, task2_id: fixture2} tasks = self.db_api.task_get_all(self.context) self.assertEqual(len(tasks), 2) self.assertEqual(set((tasks[0]['id'], tasks[1]['id'])), set((task1_id, task2_id))) for task in tasks: fixture = task_fixtures[task['id']] self.assertEqual(task['owner'], self.context.owner) self.assertEqual(task['type'], fixture['type']) self.assertEqual(task['status'], fixture['status']) self.assertEqual(task['expires_at'], fixture['expires_at']) self.assertFalse(task['deleted']) self.assertIsNone(task['deleted_at']) self.assertEqual(task['created_at'], fixture['created_at']) self.assertEqual(task['updated_at'], fixture['updated_at']) task_details_keys = ['input', 'message', 'result'] for key in task_details_keys: self.assertFalse(key in task) def test_task_create(self): task_id = str(uuid.uuid4()) self.context.tenant = str(uuid.uuid4()) values = { 'id': task_id, 'owner': self.context.owner, 'type': 'export', 'status': 'pending', } task_values = build_task_fixture(**values) task = self.db_api.task_create(self.context, task_values) self.assertIsNotNone(task) self.assertEqual(task['id'], task_id) self.assertEqual(task['owner'], self.context.owner) self.assertEqual(task['type'], 'export') self.assertEqual(task['status'], 'pending') self.assertEqual(task['input'], {'ping': 'pong'}) def test_task_create_with_all_task_info_null(self): task_id = str(uuid.uuid4()) self.context.tenant = str(uuid.uuid4()) values = { 'id': task_id, 'owner': self.context.owner, 'type': 'export', 'status': 'pending', 'input': None, 'result': None, 'message': None, } task_values = build_task_fixture(**values) task = self.db_api.task_create(self.context, task_values) self.assertIsNotNone(task) self.assertEqual(task['id'], task_id) self.assertEqual(task['owner'], self.context.owner) self.assertEqual(task['type'], 'export') self.assertEqual(task['status'], 'pending') self.assertIsNone(task['input']) self.assertIsNone(task['result']) self.assertIsNone(task['message']) def test_task_update(self): self.context.tenant = str(uuid.uuid4()) result = {'foo': 'bar'} task_values = build_task_fixture(owner=self.context.owner, result=result) task = self.db_api.task_create(self.context, task_values) task_id = task['id'] fixture = { 'status': 'processing', 'message': 'This is a error string', } task = self.db_api.task_update(self.context, task_id, fixture) self.assertEqual(task['id'], task_id) self.assertEqual(task['owner'], self.context.owner) self.assertEqual(task['type'], 'import') self.assertEqual(task['status'], 'processing') self.assertEqual(task['input'], {'ping': 'pong'}) self.assertEqual(task['result'], result) self.assertEqual(task['message'], 'This is a error string') self.assertEqual(task['deleted'], False) self.assertIsNone(task['deleted_at']) self.assertIsNone(task['expires_at']) self.assertEqual(task['created_at'], task_values['created_at']) self.assertTrue(task['updated_at'] > task['created_at']) def test_task_update_with_all_task_info_null(self): self.context.tenant = str(uuid.uuid4()) task_values = build_task_fixture(owner=self.context.owner, input=None, result=None, message=None) task = self.db_api.task_create(self.context, task_values) task_id = task['id'] fixture = {'status': 'processing'} task = self.db_api.task_update(self.context, task_id, fixture) self.assertEqual(task['id'], task_id) self.assertEqual(task['owner'], self.context.owner) self.assertEqual(task['type'], 'import') self.assertEqual(task['status'], 'processing') self.assertIsNone(task['input']) self.assertIsNone(task['result']) self.assertIsNone(task['message']) self.assertEqual(task['deleted'], False) self.assertIsNone(task['deleted_at']) self.assertIsNone(task['expires_at']) self.assertEqual(task['created_at'], task_values['created_at']) self.assertTrue(task['updated_at'] > task['created_at']) def test_task_delete(self): task_values = build_task_fixture(owner=self.context.owner) task = self.db_api.task_create(self.context, task_values) self.assertIsNotNone(task) self.assertEqual(task['deleted'], False) self.assertIsNone(task['deleted_at']) task_id = task['id'] self.db_api.task_delete(self.context, task_id) self.assertRaises(exception.TaskNotFound, self.db_api.task_get, self.context, task_id) def test_task_delete_as_admin(self): task_values = build_task_fixture(owner=self.context.owner) task = self.db_api.task_create(self.context, task_values) self.assertIsNotNone(task) self.assertEqual(task['deleted'], False) self.assertIsNone(task['deleted_at']) task_id = task['id'] self.db_api.task_delete(self.context, task_id) del_task = self.db_api.task_get(self.adm_context, task_id, force_show_deleted=True) self.assertIsNotNone(del_task) self.assertEqual(task_id, del_task['id']) self.assertEqual(True, del_task['deleted']) self.assertIsNotNone(del_task['deleted_at']) class TestVisibility(test_utils.BaseTestCase): def setUp(self): super(TestVisibility, self).setUp() self.db_api = db_tests.get_db(self.config) db_tests.reset_db(self.db_api) self.setup_tenants() self.setup_contexts() self.fixtures = self.build_image_fixtures() self.create_images(self.fixtures) def setup_tenants(self): self.admin_tenant = str(uuid.uuid4()) self.tenant1 = str(uuid.uuid4()) self.tenant2 = str(uuid.uuid4()) def setup_contexts(self): self.admin_context = context.RequestContext( is_admin=True, tenant=self.admin_tenant) self.admin_none_context = context.RequestContext( is_admin=True, tenant=None) self.tenant1_context = context.RequestContext(tenant=self.tenant1) self.tenant2_context = context.RequestContext(tenant=self.tenant2) self.none_context = context.RequestContext(tenant=None) def build_image_fixtures(self): fixtures = [] owners = { 'Unowned': None, 'Admin Tenant': self.admin_tenant, 'Tenant 1': self.tenant1, 'Tenant 2': self.tenant2, } visibilities = {'public': True, 'private': False} for owner_label, owner in owners.items(): for visibility, is_public in visibilities.items(): fixture = { 'name': '%s, %s' % (owner_label, visibility), 'owner': owner, 'is_public': is_public, } fixtures.append(fixture) return [build_image_fixture(**fixture) for fixture in fixtures] def create_images(self, images): for fixture in images: self.db_api.image_create(self.admin_context, fixture) class VisibilityTests(object): def test_unknown_admin_sees_all(self): images = self.db_api.image_get_all(self.admin_none_context) self.assertEqual(len(images), 8) def test_unknown_admin_is_public_true(self): images = self.db_api.image_get_all(self.admin_none_context, is_public=True) self.assertEqual(len(images), 4) for i in images: self.assertTrue(i['is_public']) def test_unknown_admin_is_public_false(self): images = self.db_api.image_get_all(self.admin_none_context, is_public=False) self.assertEqual(len(images), 4) for i in images: self.assertFalse(i['is_public']) def test_unknown_admin_is_public_none(self): images = self.db_api.image_get_all(self.admin_none_context) self.assertEqual(len(images), 8) def test_unknown_admin_visibility_public(self): images = self.db_api.image_get_all(self.admin_none_context, filters={'visibility': 'public'}) self.assertEqual(len(images), 4) for i in images: self.assertTrue(i['is_public']) def test_unknown_admin_visibility_private(self): images = self.db_api.image_get_all(self.admin_none_context, filters={'visibility': 'private'}) self.assertEqual(len(images), 4) for i in images: self.assertFalse(i['is_public']) def test_known_admin_sees_all(self): images = self.db_api.image_get_all(self.admin_context) self.assertEqual(len(images), 8) def test_known_admin_is_public_true(self): images = self.db_api.image_get_all(self.admin_context, is_public=True) self.assertEqual(len(images), 4) for i in images: self.assertTrue(i['is_public']) def test_known_admin_is_public_false(self): images = self.db_api.image_get_all(self.admin_context, is_public=False) self.assertEqual(len(images), 4) for i in images: self.assertFalse(i['is_public']) def test_known_admin_is_public_none(self): images = self.db_api.image_get_all(self.admin_context) self.assertEqual(len(images), 8) def test_admin_as_user_true(self): images = self.db_api.image_get_all(self.admin_context, admin_as_user=True) self.assertEqual(len(images), 5) for i in images: self.assertTrue(i['is_public'] or i['owner'] == self.admin_tenant) def test_known_admin_visibility_public(self): images = self.db_api.image_get_all(self.admin_context, filters={'visibility': 'public'}) self.assertEqual(len(images), 4) for i in images: self.assertTrue(i['is_public']) def test_known_admin_visibility_private(self): images = self.db_api.image_get_all(self.admin_context, filters={'visibility': 'private'}) self.assertEqual(len(images), 4) for i in images: self.assertFalse(i['is_public']) def test_what_unknown_user_sees(self): images = self.db_api.image_get_all(self.none_context) self.assertEqual(len(images), 4) for i in images: self.assertTrue(i['is_public']) def test_unknown_user_is_public_true(self): images = self.db_api.image_get_all(self.none_context, is_public=True) self.assertEqual(len(images), 4) for i in images: self.assertTrue(i['is_public']) def test_unknown_user_is_public_false(self): images = self.db_api.image_get_all(self.none_context, is_public=False) self.assertEqual(len(images), 0) def test_unknown_user_is_public_none(self): images = self.db_api.image_get_all(self.none_context) self.assertEqual(len(images), 4) for i in images: self.assertTrue(i['is_public']) def test_unknown_user_visibility_public(self): images = self.db_api.image_get_all(self.none_context, filters={'visibility': 'public'}) self.assertEqual(len(images), 4) for i in images: self.assertTrue(i['is_public']) def test_unknown_user_visibility_private(self): images = self.db_api.image_get_all(self.none_context, filters={'visibility': 'private'}) self.assertEqual(len(images), 0) def test_what_tenant1_sees(self): images = self.db_api.image_get_all(self.tenant1_context) self.assertEqual(len(images), 5) for i in images: if not i['is_public']: self.assertEqual(i['owner'], self.tenant1) def test_tenant1_is_public_true(self): images = self.db_api.image_get_all(self.tenant1_context, is_public=True) self.assertEqual(len(images), 4) for i in images: self.assertTrue(i['is_public']) def test_tenant1_is_public_false(self): images = self.db_api.image_get_all(self.tenant1_context, is_public=False) self.assertEqual(len(images), 1) self.assertFalse(images[0]['is_public']) self.assertEqual(images[0]['owner'], self.tenant1) def test_tenant1_is_public_none(self): images = self.db_api.image_get_all(self.tenant1_context) self.assertEqual(len(images), 5) for i in images: if not i['is_public']: self.assertEqual(i['owner'], self.tenant1) def test_tenant1_visibility_public(self): images = self.db_api.image_get_all(self.tenant1_context, filters={'visibility': 'public'}) self.assertEqual(len(images), 4) for i in images: self.assertTrue(i['is_public']) def test_tenant1_visibility_private(self): images = self.db_api.image_get_all(self.tenant1_context, filters={'visibility': 'private'}) self.assertEqual(len(images), 1) self.assertFalse(images[0]['is_public']) self.assertEqual(images[0]['owner'], self.tenant1) def _setup_is_public_red_herring(self): values = { 'name': 'Red Herring', 'owner': self.tenant1, 'is_public': False, 'properties': {'is_public': 'silly'} } fixture = build_image_fixture(**values) self.db_api.image_create(self.admin_context, fixture) def test_is_public_is_a_normal_filter_for_admin(self): self._setup_is_public_red_herring() images = self.db_api.image_get_all(self.admin_context, filters={'is_public': 'silly'}) self.assertEqual(len(images), 1) self.assertEqual(images[0]['name'], 'Red Herring') def test_is_public_is_a_normal_filter_for_user(self): self._setup_is_public_red_herring() images = self.db_api.image_get_all(self.tenant1_context, filters={'is_public': 'silly'}) self.assertEqual(len(images), 1) self.assertEqual(images[0]['name'], 'Red Herring') # NOTE(markwash): the following tests are sanity checks to make sure # visibility filtering and is_public=(True|False) do not interact in # unexpected ways. However, using both of the filtering techniques # simultaneously is not an anticipated use case. def test_admin_is_public_true_and_visibility_public(self): images = self.db_api.image_get_all(self.admin_context, is_public=True, filters={'visibility': 'public'}) self.assertEqual(len(images), 4) def test_admin_is_public_false_and_visibility_public(self): images = self.db_api.image_get_all(self.admin_context, is_public=False, filters={'visibility': 'public'}) self.assertEqual(len(images), 0) def test_admin_is_public_true_and_visibility_private(self): images = self.db_api.image_get_all(self.admin_context, is_public=True, filters={'visibility': 'private'}) self.assertEqual(len(images), 0) def test_admin_is_public_false_and_visibility_private(self): images = self.db_api.image_get_all(self.admin_context, is_public=False, filters={'visibility': 'private'}) self.assertEqual(len(images), 4) def test_tenant1_is_public_true_and_visibility_public(self): images = self.db_api.image_get_all(self.tenant1_context, is_public=True, filters={'visibility': 'public'}) self.assertEqual(len(images), 4) def test_tenant1_is_public_false_and_visibility_public(self): images = self.db_api.image_get_all(self.tenant1_context, is_public=False, filters={'visibility': 'public'}) self.assertEqual(len(images), 0) def test_tenant1_is_public_true_and_visibility_private(self): images = self.db_api.image_get_all(self.tenant1_context, is_public=True, filters={'visibility': 'private'}) self.assertEqual(len(images), 0) def test_tenant1_is_public_false_and_visibility_private(self): images = self.db_api.image_get_all(self.tenant1_context, is_public=False, filters={'visibility': 'private'}) self.assertEqual(len(images), 1) class TestMembershipVisibility(test_utils.BaseTestCase): def setUp(self): super(TestMembershipVisibility, self).setUp() self.db_api = db_tests.get_db(self.config) db_tests.reset_db(self.db_api) self._create_contexts() self._create_images() def _create_contexts(self): self.owner1, self.owner1_ctx = self._user_fixture() self.owner2, self.owner2_ctx = self._user_fixture() self.tenant1, self.user1_ctx = self._user_fixture() self.tenant2, self.user2_ctx = self._user_fixture() self.tenant3, self.user3_ctx = self._user_fixture() self.admin_tenant, self.admin_ctx = self._user_fixture(admin=True) def _user_fixture(self, admin=False): tenant_id = str(uuid.uuid4()) ctx = context.RequestContext(tenant=tenant_id, is_admin=admin) return tenant_id, ctx def _create_images(self): self.image_ids = {} for owner in [self.owner1, self.owner2]: self._create_image('not_shared', owner) self._create_image('shared-with-1', owner, members=[self.tenant1]) self._create_image('shared-with-2', owner, members=[self.tenant2]) self._create_image('shared-with-both', owner, members=[self.tenant1, self.tenant2]) def _create_image(self, name, owner, members=None): image = build_image_fixture(name=name, owner=owner, is_public=False) self.image_ids[(owner, name)] = image['id'] self.db_api.image_create(self.admin_ctx, image) for member in members or []: member = {'image_id': image['id'], 'member': member} self.db_api.image_member_create(self.admin_ctx, member) class MembershipVisibilityTests(object): def _check_by_member(self, ctx, member_id, expected): members = self.db_api.image_member_find(ctx, member=member_id) images = [self.db_api.image_get(self.admin_ctx, member['image_id']) for member in members] facets = [(image['owner'], image['name']) for image in images] self.assertEqual(set(expected), set(facets)) def test_owner1_finding_user1_memberships(self): """Owner1 should see images it owns that are shared with User1.""" expected = [ (self.owner1, 'shared-with-1'), (self.owner1, 'shared-with-both'), ] self._check_by_member(self.owner1_ctx, self.tenant1, expected) def test_user1_finding_user1_memberships(self): """User1 should see all images shared with User1 """ expected = [ (self.owner1, 'shared-with-1'), (self.owner1, 'shared-with-both'), (self.owner2, 'shared-with-1'), (self.owner2, 'shared-with-both'), ] self._check_by_member(self.user1_ctx, self.tenant1, expected) def test_user2_finding_user1_memberships(self): """User2 should see no images shared with User1 """ expected = [] self._check_by_member(self.user2_ctx, self.tenant1, expected) def test_admin_finding_user1_memberships(self): """Admin should see all images shared with User1 """ expected = [ (self.owner1, 'shared-with-1'), (self.owner1, 'shared-with-both'), (self.owner2, 'shared-with-1'), (self.owner2, 'shared-with-both'), ] self._check_by_member(self.admin_ctx, self.tenant1, expected) def _check_by_image(self, context, image_id, expected): members = self.db_api.image_member_find(context, image_id=image_id) member_ids = [member['member'] for member in members] self.assertEqual(set(expected), set(member_ids)) def test_owner1_finding_owner1s_image_members(self): """Owner1 should see all memberships of its image """ expected = [self.tenant1, self.tenant2] image_id = self.image_ids[(self.owner1, 'shared-with-both')] self._check_by_image(self.owner1_ctx, image_id, expected) def test_admin_finding_owner1s_image_members(self): """Admin should see all memberships of owner1's image """ expected = [self.tenant1, self.tenant2] image_id = self.image_ids[(self.owner1, 'shared-with-both')] self._check_by_image(self.admin_ctx, image_id, expected) def test_user1_finding_owner1s_image_members(self): """User1 should see its own membership of owner1's image """ expected = [self.tenant1] image_id = self.image_ids[(self.owner1, 'shared-with-both')] self._check_by_image(self.user1_ctx, image_id, expected) def test_user2_finding_owner1s_image_members(self): """User2 should see its own membership of owner1's image """ expected = [self.tenant2] image_id = self.image_ids[(self.owner1, 'shared-with-both')] self._check_by_image(self.user2_ctx, image_id, expected) def test_user3_finding_owner1s_image_members(self): """User3 should see no memberships of owner1's image """ expected = [] image_id = self.image_ids[(self.owner1, 'shared-with-both')] self._check_by_image(self.user3_ctx, image_id, expected) glance-2014.1/glance/tests/functional/db/test_simple.py0000664000175400017540000000406412323736226024226 0ustar jenkinsjenkins00000000000000# Copyright 2012 OpenStack Foundation # Copyright 2013 IBM Corp. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from glance.api import CONF import glance.db.simple.api import glance.tests.functional.db as db_tests from glance.tests.functional.db import base def get_db(config): CONF.set_override('data_api', 'glance.db.simple.api') db_api = glance.db.get_api() return db_api def reset_db(db_api): db_api.reset() class TestSimpleDriver(base.TestDriver, base.DriverTests): def setUp(self): db_tests.load(get_db, reset_db) super(TestSimpleDriver, self).setUp() self.addCleanup(db_tests.reset) class TestSimpleQuota(base.DriverQuotaTests): def setUp(self): db_tests.load(get_db, reset_db) super(TestSimpleQuota, self).setUp() self.addCleanup(db_tests.reset) class TestSimpleVisibility(base.TestVisibility, base.VisibilityTests): def setUp(self): db_tests.load(get_db, reset_db) super(TestSimpleVisibility, self).setUp() self.addCleanup(db_tests.reset) class TestSimpleMembershipVisibility(base.TestMembershipVisibility, base.MembershipVisibilityTests): def setUp(self): db_tests.load(get_db, reset_db) super(TestSimpleMembershipVisibility, self).setUp() self.addCleanup(db_tests.reset) class TestSimpleTask(base.TaskTests): def setUp(self): db_tests.load(get_db, reset_db) super(TestSimpleTask, self).setUp() self.addCleanup(db_tests.reset) glance-2014.1/glance/tests/functional/db/__init__.py0000664000175400017540000000206512323736226023434 0ustar jenkinsjenkins00000000000000# Copyright 2012 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # NOTE(markwash): These functions are used in the base tests cases to # set up the db api implementation under test. Rather than accessing them # directly, test modules should use the load and reset functions below. get_db = None reset_db = None def load(get_db_fn, reset_db_fn): global get_db, reset_db get_db = get_db_fn reset_db = reset_db_fn def reset(): global get_db, reset_db get_db = None reset_db = None glance-2014.1/glance/tests/functional/store_utils.py0000664000175400017540000000524112323736226023663 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation # 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. """ Utility methods to set testcases up for Swift and/or S3 tests. """ from __future__ import print_function import BaseHTTPServer import thread from glance.openstack.common import units FIVE_KB = 5 * units.Ki class RemoteImageHandler(BaseHTTPServer.BaseHTTPRequestHandler): def do_HEAD(self): """ Respond to an image HEAD request fake metadata """ if 'images' in self.path: self.send_response(200) self.send_header('Content-Type', 'application/octet-stream') self.send_header('Content-Length', FIVE_KB) self.end_headers() return else: self.send_error(404, 'File Not Found: %s' % self.path) return def do_GET(self): """ Respond to an image GET request with fake image content. """ if 'images' in self.path: self.send_response(200) self.send_header('Content-Type', 'application/octet-stream') self.send_header('Content-Length', FIVE_KB) self.end_headers() image_data = '*' * FIVE_KB self.wfile.write(image_data) self.wfile.close() return else: self.send_error(404, 'File Not Found: %s' % self.path) return def log_message(self, format, *args): """ Simple override to prevent writing crap to stderr... """ pass def setup_http(test): server_class = BaseHTTPServer.HTTPServer remote_server = server_class(('127.0.0.1', 0), RemoteImageHandler) remote_ip, remote_port = remote_server.server_address def serve_requests(httpd): httpd.serve_forever() thread.start_new_thread(serve_requests, (remote_server,)) test.http_server = remote_server test.http_ip = remote_ip test.http_port = remote_port test.addCleanup(test.http_server.shutdown) def get_http_uri(test, image_id): uri = 'http://%(http_ip)s:%(http_port)d/images/' % test.__dict__ uri += image_id return uri glance-2014.1/glance/tests/functional/__init__.py0000664000175400017540000010532712323736230023047 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ Base test class for running non-stubbed tests (functional tests) The FunctionalTest class contains helper methods for starting the API and Registry server, grabbing the logs of each, cleaning up pidfiles, and spinning down the servers. """ import atexit import datetime import logging import os import re import shutil import signal import socket import sys import tempfile import time import fixtures import six.moves.urllib.parse as urlparse import testtools from glance.common import utils from glance.db.sqlalchemy import api as db_api from glance.openstack.common import jsonutils from glance.openstack.common import units from glance import tests as glance_tests from glance.tests import utils as test_utils execute, get_unused_port = test_utils.execute, test_utils.get_unused_port class Server(object): """ Class used to easily manage starting and stopping a server during functional test runs. """ def __init__(self, test_dir, port, sock=None): """ Creates a new Server object. :param test_dir: The directory where all test stuff is kept. This is passed from the FunctionalTestCase. :param port: The port to start a server up on. """ self.verbose = True self.debug = True self.no_venv = False self.test_dir = test_dir self.bind_port = port self.conf_file_name = None self.conf_base = None self.paste_conf_base = None self.exec_env = None self.deployment_flavor = '' self.show_image_direct_url = False self.show_multiple_locations = False self.property_protection_file = '' self.enable_v1_api = True self.enable_v2_api = True self.enable_v1_registry = True self.enable_v2_registry = True self.needs_database = False self.log_file = None self.sock = sock self.fork_socket = True self.process_pid = None self.server_module = None self.stop_kill = False def write_conf(self, **kwargs): """ Writes the configuration file for the server to its intended destination. Returns the name of the configuration file and the over-ridden config content (may be useful for populating error messages). """ if not self.conf_base: raise RuntimeError("Subclass did not populate config_base!") conf_override = self.__dict__.copy() if kwargs: conf_override.update(**kwargs) # A config file and paste.ini to use just for this test...we don't want # to trample on currently-running Glance servers, now do we? conf_dir = os.path.join(self.test_dir, 'etc') conf_filepath = os.path.join(conf_dir, "%s.conf" % self.server_name) if os.path.exists(conf_filepath): os.unlink(conf_filepath) paste_conf_filepath = conf_filepath.replace(".conf", "-paste.ini") if os.path.exists(paste_conf_filepath): os.unlink(paste_conf_filepath) utils.safe_mkdirs(conf_dir) def override_conf(filepath, overridden): with open(filepath, 'wb') as conf_file: conf_file.write(overridden) conf_file.flush() return conf_file.name overridden_core = self.conf_base % conf_override self.conf_file_name = override_conf(conf_filepath, overridden_core) overridden_paste = '' if self.paste_conf_base: overridden_paste = self.paste_conf_base % conf_override override_conf(paste_conf_filepath, overridden_paste) overridden = ('==Core config==\n%s\n==Paste config==\n%s' % (overridden_core, overridden_paste)) return self.conf_file_name, overridden def start(self, expect_exit=True, expected_exitcode=0, **kwargs): """ Starts the server. Any kwargs passed to this method will override the configuration value in the conf file used in starting the servers. """ # Ensure the configuration file is written self.write_conf(**kwargs) self.create_database() cmd = ("%(server_module)s --config-file %(conf_file_name)s" % self.__dict__) cmd = "%s -m %s" % (sys.executable, cmd) # close the sock and release the unused port closer to start time if self.exec_env: exec_env = self.exec_env.copy() else: exec_env = {} if self.sock: if not self.fork_socket: self.sock.close() self.sock = None else: fd = os.dup(self.sock.fileno()) exec_env[utils.GLANCE_TEST_SOCKET_FD_STR] = str(fd) self.sock.close() self.process_pid = test_utils.fork_exec(cmd, logfile=os.devnull, exec_env=exec_env) self.stop_kill = not expect_exit if self.pid_file: pf = open(self.pid_file, 'w') pf.write('%d\n' % self.process_pid) pf.close() if not expect_exit: rc = 0 try: os.kill(self.process_pid, 0) except OSError: raise RuntimeError("The process did not start") else: rc = test_utils.wait_for_fork( self.process_pid, expected_exitcode=expected_exitcode) # avoid an FD leak if self.sock: os.close(fd) self.sock = None return (rc, '', '') def reload(self, expect_exit=True, expected_exitcode=0, **kwargs): """ Start and stop the service to reload Any kwargs passed to this method will override the configuration value in the conf file used in starting the servers. """ self.stop() return self.start(expect_exit=expect_exit, expected_exitcode=expected_exitcode, **kwargs) def create_database(self): """Create database if required for this server""" if self.needs_database: conf_dir = os.path.join(self.test_dir, 'etc') utils.safe_mkdirs(conf_dir) conf_filepath = os.path.join(conf_dir, 'glance-manage.conf') with open(conf_filepath, 'wb') as conf_file: conf_file.write('[DEFAULT]\n') conf_file.write('sql_connection = %s' % self.sql_connection) conf_file.flush() glance_db_env = 'GLANCE_DB_TEST_SQLITE_FILE' if glance_db_env in os.environ: # use the empty db created and cached as a tempfile # instead of spending the time creating a new one db_location = os.environ[glance_db_env] os.system('cp %s %s/tests.sqlite' % (db_location, self.test_dir)) else: cmd = ('%s -m glance.cmd.manage --config-file %s db sync' % (sys.executable, conf_filepath)) execute(cmd, no_venv=self.no_venv, exec_env=self.exec_env, expect_exit=True) # copy the clean db to a temp location so that it # can be reused for future tests (osf, db_location) = tempfile.mkstemp() os.close(osf) os.system('cp %s/tests.sqlite %s' % (self.test_dir, db_location)) os.environ[glance_db_env] = db_location # cleanup the temp file when the test suite is # complete def _delete_cached_db(): try: os.remove(os.environ[glance_db_env]) except Exception: glance_tests.logger.exception( "Error cleaning up the file %s" % os.environ[glance_db_env]) atexit.register(_delete_cached_db) def stop(self): """ Spin down the server. """ if not self.process_pid: raise Exception('why is this being called? %s' % self.server_name) if self.stop_kill: os.kill(self.process_pid, signal.SIGTERM) rc = test_utils.wait_for_fork(self.process_pid, raise_error=False) return (rc, '', '') def dump_log(self, name): log = logging.getLogger(name) if not self.log_file or not os.path.exists(self.log_file): return fptr = open(self.log_file, 'r') for line in fptr: log.info(line.strip()) class ApiServer(Server): """ Server object that starts/stops/manages the API server """ def __init__(self, test_dir, port, policy_file, delayed_delete=False, pid_file=None, sock=None, **kwargs): super(ApiServer, self).__init__(test_dir, port, sock=sock) self.server_name = 'api' self.server_module = 'glance.cmd.%s' % self.server_name self.default_store = kwargs.get("default_store", "file") self.key_file = "" self.cert_file = "" self.metadata_encryption_key = "012345678901234567890123456789ab" self.image_dir = os.path.join(self.test_dir, "images") self.pid_file = pid_file or os.path.join(self.test_dir, "api.pid") self.scrubber_datadir = os.path.join(self.test_dir, "scrubber") self.log_file = os.path.join(self.test_dir, "api.log") self.s3_store_host = "s3.amazonaws.com" self.s3_store_access_key = "" self.s3_store_secret_key = "" self.s3_store_bucket = "" self.s3_store_bucket_url_format = "" self.swift_store_auth_version = kwargs.get("swift_store_auth_version", "2") self.swift_store_auth_address = kwargs.get("swift_store_auth_address", "") self.swift_store_user = kwargs.get("swift_store_user", "") self.swift_store_key = kwargs.get("swift_store_key", "") self.swift_store_container = kwargs.get("swift_store_container", "") self.swift_store_create_container_on_put = kwargs.get( "swift_store_create_container_on_put", "True") self.swift_store_large_object_size = 5 * units.Ki self.swift_store_large_object_chunk_size = 200 self.swift_store_multi_tenant = False self.swift_store_admin_tenants = [] self.rbd_store_ceph_conf = "" self.rbd_store_pool = "" self.rbd_store_user = "" self.rbd_store_chunk_size = 4 self.delayed_delete = delayed_delete self.owner_is_tenant = True self.workers = 0 self.scrub_time = 5 self.image_cache_dir = os.path.join(self.test_dir, 'cache') self.image_cache_driver = 'sqlite' self.policy_file = policy_file self.policy_default_rule = 'default' self.property_protection_rule_format = 'roles' self.image_member_quota = 10 self.image_property_quota = 10 self.image_tag_quota = 10 self.image_location_quota = 2 self.needs_database = True default_sql_connection = 'sqlite:////%s/tests.sqlite' % self.test_dir self.sql_connection = os.environ.get('GLANCE_TEST_SQL_CONNECTION', default_sql_connection) self.user_storage_quota = 0 self.lock_path = self.test_dir self.location_strategy = 'location_order' self.store_type_location_strategy_preference = "" self.conf_base = """[DEFAULT] verbose = %(verbose)s debug = %(debug)s default_log_levels = eventlet.wsgi.server=DEBUG filesystem_store_datadir=%(image_dir)s default_store = %(default_store)s bind_host = 127.0.0.1 bind_port = %(bind_port)s key_file = %(key_file)s cert_file = %(cert_file)s metadata_encryption_key = %(metadata_encryption_key)s registry_host = 127.0.0.1 registry_port = %(registry_port)s log_file = %(log_file)s s3_store_host = %(s3_store_host)s s3_store_access_key = %(s3_store_access_key)s s3_store_secret_key = %(s3_store_secret_key)s s3_store_bucket = %(s3_store_bucket)s s3_store_bucket_url_format = %(s3_store_bucket_url_format)s swift_store_auth_version = %(swift_store_auth_version)s swift_store_auth_address = %(swift_store_auth_address)s swift_store_user = %(swift_store_user)s swift_store_key = %(swift_store_key)s swift_store_container = %(swift_store_container)s swift_store_create_container_on_put = %(swift_store_create_container_on_put)s swift_store_large_object_size = %(swift_store_large_object_size)s swift_store_large_object_chunk_size = %(swift_store_large_object_chunk_size)s swift_store_multi_tenant = %(swift_store_multi_tenant)s swift_store_admin_tenants = %(swift_store_admin_tenants)s rbd_store_chunk_size = %(rbd_store_chunk_size)s rbd_store_user = %(rbd_store_user)s rbd_store_pool = %(rbd_store_pool)s rbd_store_ceph_conf = %(rbd_store_ceph_conf)s delayed_delete = %(delayed_delete)s owner_is_tenant = %(owner_is_tenant)s workers = %(workers)s scrub_time = %(scrub_time)s scrubber_datadir = %(scrubber_datadir)s image_cache_dir = %(image_cache_dir)s image_cache_driver = %(image_cache_driver)s policy_file = %(policy_file)s policy_default_rule = %(policy_default_rule)s db_auto_create = False sql_connection = %(sql_connection)s show_image_direct_url = %(show_image_direct_url)s show_multiple_locations = %(show_multiple_locations)s user_storage_quota = %(user_storage_quota)s enable_v1_api = %(enable_v1_api)s enable_v2_api = %(enable_v2_api)s lock_path = %(lock_path)s enable_v2_api= %(enable_v2_api)s property_protection_file = %(property_protection_file)s property_protection_rule_format = %(property_protection_rule_format)s image_member_quota=%(image_member_quota)s image_property_quota=%(image_property_quota)s image_tag_quota=%(image_tag_quota)s image_location_quota=%(image_location_quota)s location_strategy=%(location_strategy)s [paste_deploy] flavor = %(deployment_flavor)s [store_type_location_strategy] store_type_preference = %(store_type_location_strategy_preference)s """ self.paste_conf_base = """[pipeline:glance-api] pipeline = versionnegotiation gzip unauthenticated-context rootapp [pipeline:glance-api-caching] pipeline = versionnegotiation gzip unauthenticated-context cache rootapp [pipeline:glance-api-cachemanagement] pipeline = versionnegotiation gzip unauthenticated-context cache cache_manage rootapp [pipeline:glance-api-fakeauth] pipeline = versionnegotiation gzip fakeauth context rootapp [pipeline:glance-api-noauth] pipeline = versionnegotiation gzip context rootapp [composite:rootapp] paste.composite_factory = glance.api:root_app_factory /: apiversions /v1: apiv1app /v2: apiv2app [app:apiversions] paste.app_factory = glance.api.versions:create_resource [app:apiv1app] paste.app_factory = glance.api.v1.router:API.factory [app:apiv2app] paste.app_factory = glance.api.v2.router:API.factory [filter:versionnegotiation] paste.filter_factory = glance.api.middleware.version_negotiation:VersionNegotiationFilter.factory [filter:gzip] paste.filter_factory = glance.api.middleware.gzip:GzipMiddleware.factory [filter:cache] paste.filter_factory = glance.api.middleware.cache:CacheFilter.factory [filter:cache_manage] paste.filter_factory = glance.api.middleware.cache_manage:CacheManageFilter.factory [filter:context] paste.filter_factory = glance.api.middleware.context:ContextMiddleware.factory [filter:unauthenticated-context] paste.filter_factory = glance.api.middleware.context:UnauthenticatedContextMiddleware.factory [filter:fakeauth] paste.filter_factory = glance.tests.utils:FakeAuthMiddleware.factory """ class RegistryServer(Server): """ Server object that starts/stops/manages the Registry server """ def __init__(self, test_dir, port, sock=None): super(RegistryServer, self).__init__(test_dir, port, sock=sock) self.server_name = 'registry' self.server_module = 'glance.cmd.%s' % self.server_name self.needs_database = True default_sql_connection = 'sqlite:////%s/tests.sqlite' % self.test_dir self.sql_connection = os.environ.get('GLANCE_TEST_SQL_CONNECTION', default_sql_connection) self.pid_file = os.path.join(self.test_dir, "registry.pid") self.log_file = os.path.join(self.test_dir, "registry.log") self.owner_is_tenant = True self.workers = 0 self.api_version = 1 self.user_storage_quota = 0 self.conf_base = """[DEFAULT] verbose = %(verbose)s debug = %(debug)s bind_host = 127.0.0.1 bind_port = %(bind_port)s log_file = %(log_file)s db_auto_create = False sql_connection = %(sql_connection)s sql_idle_timeout = 3600 api_limit_max = 1000 limit_param_default = 25 owner_is_tenant = %(owner_is_tenant)s enable_v2_registry = %(enable_v2_registry)s workers = %(workers)s user_storage_quota = %(user_storage_quota)s [paste_deploy] flavor = %(deployment_flavor)s """ self.paste_conf_base = """[pipeline:glance-registry] pipeline = unauthenticated-context registryapp [pipeline:glance-registry-fakeauth] pipeline = fakeauth context registryapp [app:registryapp] paste.app_factory = glance.registry.api:API.factory [filter:context] paste.filter_factory = glance.api.middleware.context:ContextMiddleware.factory [filter:unauthenticated-context] paste.filter_factory = glance.api.middleware.context:UnauthenticatedContextMiddleware.factory [filter:fakeauth] paste.filter_factory = glance.tests.utils:FakeAuthMiddleware.factory """ class ScrubberDaemon(Server): """ Server object that starts/stops/manages the Scrubber server """ def __init__(self, test_dir, daemon=False, **kwargs): # NOTE(jkoelker): Set the port to 0 since we actually don't listen super(ScrubberDaemon, self).__init__(test_dir, 0) self.server_name = 'scrubber' self.server_module = 'glance.cmd.%s' % self.server_name self.daemon = daemon self.image_dir = os.path.join(self.test_dir, "images") self.scrubber_datadir = os.path.join(self.test_dir, "scrubber") self.pid_file = os.path.join(self.test_dir, "scrubber.pid") self.log_file = os.path.join(self.test_dir, "scrubber.log") self.swift_store_auth_address = kwargs.get("swift_store_auth_address", "") self.swift_store_user = kwargs.get("swift_store_user", "") self.swift_store_key = kwargs.get("swift_store_key", "") self.swift_store_container = kwargs.get("swift_store_container", "") self.swift_store_auth_version = kwargs.get("swift_store_auth_version", "2") self.metadata_encryption_key = "012345678901234567890123456789ab" self.lock_path = self.test_dir self.conf_base = """[DEFAULT] verbose = %(verbose)s debug = %(debug)s filesystem_store_datadir=%(image_dir)s log_file = %(log_file)s daemon = %(daemon)s wakeup_time = 2 scrubber_datadir = %(scrubber_datadir)s registry_host = 127.0.0.1 registry_port = %(registry_port)s metadata_encryption_key = %(metadata_encryption_key)s swift_store_auth_address = %(swift_store_auth_address)s swift_store_user = %(swift_store_user)s swift_store_key = %(swift_store_key)s swift_store_container = %(swift_store_container)s swift_store_auth_version = %(swift_store_auth_version)s lock_path = %(lock_path)s """ def start(self, expect_exit=True, expected_exitcode=0, **kwargs): if 'daemon' in kwargs: expect_exit = False return super(ScrubberDaemon, self).start( expect_exit=expect_exit, expected_exitcode=expected_exitcode, **kwargs) class FunctionalTest(test_utils.BaseTestCase): """ Base test class for any test that wants to test the actual servers and clients and not just the stubbed out interfaces """ inited = False disabled = False launched_servers = [] def setUp(self): super(FunctionalTest, self).setUp() self.test_dir = self.useFixture(fixtures.TempDir()).path self.api_protocol = 'http' self.api_port, api_sock = test_utils.get_unused_port_and_socket() self.registry_port, registry_sock = \ test_utils.get_unused_port_and_socket() conf_dir = os.path.join(self.test_dir, 'etc') utils.safe_mkdirs(conf_dir) self.copy_data_file('schema-image.json', conf_dir) self.copy_data_file('policy.json', conf_dir) self.copy_data_file('property-protections.conf', conf_dir) self.copy_data_file('property-protections-policies.conf', conf_dir) self.property_file_roles = os.path.join(conf_dir, 'property-protections.conf') property_policies = 'property-protections-policies.conf' self.property_file_policies = os.path.join(conf_dir, property_policies) self.policy_file = os.path.join(conf_dir, 'policy.json') self.api_server = ApiServer(self.test_dir, self.api_port, self.policy_file, sock=api_sock) self.registry_server = RegistryServer(self.test_dir, self.registry_port, sock=registry_sock) self.scrubber_daemon = ScrubberDaemon(self.test_dir) self.pid_files = [self.api_server.pid_file, self.registry_server.pid_file, self.scrubber_daemon.pid_file] self.files_to_destroy = [] self.launched_servers = [] def tearDown(self): if not self.disabled: self.cleanup() # We destroy the test data store between each test case, # and recreate it, which ensures that we have no side-effects # from the tests self._reset_database(self.registry_server.sql_connection) self._reset_database(self.api_server.sql_connection) super(FunctionalTest, self).tearDown() self.api_server.dump_log('api_server') self.registry_server.dump_log('registry_server') self.scrubber_daemon.dump_log('scrubber_daemon') def set_policy_rules(self, rules): fap = open(self.policy_file, 'w') fap.write(jsonutils.dumps(rules)) fap.close() def _reset_database(self, conn_string): conn_pieces = urlparse.urlparse(conn_string) if conn_string.startswith('sqlite'): # We leave behind the sqlite DB for failing tests to aid # in diagnosis, as the file size is relatively small and # won't interfere with subsequent tests as it's in a per- # test directory (which is blown-away if the test is green) pass elif conn_string.startswith('mysql'): # We can execute the MySQL client to destroy and re-create # the MYSQL database, which is easier and less error-prone # than using SQLAlchemy to do this via MetaData...trust me. database = conn_pieces.path.strip('/') loc_pieces = conn_pieces.netloc.split('@') host = loc_pieces[1] auth_pieces = loc_pieces[0].split(':') user = auth_pieces[0] password = "" if len(auth_pieces) > 1: if auth_pieces[1].strip(): password = "-p%s" % auth_pieces[1] sql = ("drop database if exists %(database)s; " "create database %(database)s;") % {'database': database} cmd = ("mysql -u%(user)s %(password)s -h%(host)s " "-e\"%(sql)s\"") % {'user': user, 'password': password, 'host': host, 'sql': sql} exitcode, out, err = execute(cmd) self.assertEqual(0, exitcode) def cleanup(self): """ Makes sure anything we created or started up in the tests are destroyed or spun down """ # NOTE(jbresnah) call stop on each of the servers instead of # checking the pid file. stop() will wait until the child # server is dead. This eliminates the possibility of a race # between a child process listening on a port actually dying # and a new process being started servers = [self.api_server, self.registry_server, self.scrubber_daemon] for s in servers: try: s.stop() except Exception: pass for f in self.files_to_destroy: if os.path.exists(f): os.unlink(f) def start_server(self, server, expect_launch, expect_exit=True, expected_exitcode=0, **kwargs): """ Starts a server on an unused port. Any kwargs passed to this method will override the configuration value in the conf file used in starting the server. :param server: the server to launch :param expect_launch: true iff the server is expected to successfully start :param expect_exit: true iff the launched process is expected to exit in a timely fashion :param expected_exitcode: expected exitcode from the launcher """ self.cleanup() # Start up the requested server exitcode, out, err = server.start(expect_exit=expect_exit, expected_exitcode=expected_exitcode, **kwargs) if expect_exit: self.assertEqual(expected_exitcode, exitcode, "Failed to spin up the requested server. " "Got: %s" % err) self.launched_servers.append(server) launch_msg = self.wait_for_servers([server], expect_launch) self.assertTrue(launch_msg is None, launch_msg) def start_with_retry(self, server, port_name, max_retries, expect_launch=True, **kwargs): """ Starts a server, with retries if the server launches but fails to start listening on the expected port. :param server: the server to launch :param port_name: the name of the port attribute :param max_retries: the maximum number of attempts :param expect_launch: true iff the server is expected to successfully start :param expect_exit: true iff the launched process is expected to exit in a timely fashion """ launch_msg = None for i in range(max_retries): exitcode, out, err = server.start(expect_exit=not expect_launch, **kwargs) name = server.server_name self.assertEqual(0, exitcode, "Failed to spin up the %s server. " "Got: %s" % (name, err)) launch_msg = self.wait_for_servers([server], expect_launch) if launch_msg: server.stop() server.bind_port = get_unused_port() setattr(self, port_name, server.bind_port) else: self.launched_servers.append(server) break self.assertTrue(launch_msg is None, launch_msg) def start_servers(self, **kwargs): """ Starts the API and Registry servers (glance-control api start & glance-control registry start) on unused ports. glance-control should be installed into the python path Any kwargs passed to this method will override the configuration value in the conf file used in starting the servers. """ self.cleanup() # Start up the API and default registry server # We start the registry server first, as the API server config # depends on the registry port - this ordering allows for # retrying the launch on a port clash self.start_with_retry(self.registry_server, 'registry_port', 3, **kwargs) kwargs['registry_port'] = self.registry_server.bind_port self.start_with_retry(self.api_server, 'api_port', 3, **kwargs) exitcode, out, err = self.scrubber_daemon.start(**kwargs) self.assertEqual(0, exitcode, "Failed to spin up the Scrubber daemon. " "Got: %s" % err) def ping_server(self, port): """ Simple ping on the port. If responsive, return True, else return False. :note We use raw sockets, not ping here, since ping uses ICMP and has no concept of ports... """ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: s.connect(("127.0.0.1", port)) s.close() return True except socket.error: return False def wait_for_servers(self, servers, expect_launch=True, timeout=10): """ Tight loop, waiting for the given server port(s) to be available. Returns when all are pingable. There is a timeout on waiting for the servers to come up. :param servers: Glance server ports to ping :param expect_launch: Optional, true iff the server(s) are expected to successfully start :param timeout: Optional, defaults to 3 seconds :return: None if launch expectation is met, otherwise an assertion message """ now = datetime.datetime.now() timeout_time = now + datetime.timedelta(seconds=timeout) replied = [] while (timeout_time > now): pinged = 0 for server in servers: if self.ping_server(server.bind_port): pinged += 1 if server not in replied: replied.append(server) if pinged == len(servers): msg = 'Unexpected server launch status' return None if expect_launch else msg now = datetime.datetime.now() time.sleep(0.05) failed = list(set(servers) - set(replied)) msg = 'Unexpected server launch status for: ' for f in failed: msg += ('%s, ' % f.server_name) if os.path.exists(f.pid_file): pid = f.process_pid trace = f.pid_file.replace('.pid', '.trace') cmd = 'strace -p %d -o %s' % (pid, trace) execute(cmd, raise_error=False, expect_exit=False) time.sleep(0.5) if os.path.exists(trace): msg += ('\nstrace:\n%s\n' % open(trace).read()) self.add_log_details(failed) return msg if expect_launch else None def reload_server(self, server, expect_launch, expect_exit=True, expected_exitcode=0, **kwargs): """ Reload a running server Any kwargs passed to this method will override the configuration value in the conf file used in starting the server. :param server: the server to launch :param expect_launch: true iff the server is expected to successfully start :param expect_exit: true iff the launched process is expected to exit in a timely fashion :param expected_exitcode: expected exitcode from the launcher """ self.cleanup() # Start up the requested server exitcode, out, err = server.reload(expect_exit=expect_exit, expected_exitcode=expected_exitcode, **kwargs) if expect_exit: self.assertEqual(expected_exitcode, exitcode, "Failed to spin up the requested server. " "Got: %s" % err) self.assertTrue(re.search("Restarting glance-[a-z]+ with", out)) self.launched_servers.append(server) launch_msg = self.wait_for_servers([server], expect_launch) self.assertTrue(launch_msg is None, launch_msg) def stop_server(self, server, name): """ Called to stop a single server in a normal fashion using the glance-control stop method to gracefully shut the server down. :param server: the server to stop """ # Spin down the requested server server.stop() def stop_servers(self): """ Called to stop the started servers in a normal fashion. Note that cleanup() will stop the servers using a fairly draconian method of sending a SIGTERM signal to the servers. Here, we use the glance-control stop method to gracefully shut the server down. This method also asserts that the shutdown was clean, and so it is meant to be called during a normal test case sequence. """ # Spin down the API and default registry server self.stop_server(self.api_server, 'API server') self.stop_server(self.registry_server, 'Registry server') self.stop_server(self.scrubber_daemon, 'Scrubber daemon') self._reset_database(self.registry_server.sql_connection) def run_sql_cmd(self, sql): """ Provides a crude mechanism to run manual SQL commands for backend DB verification within the functional tests. The raw result set is returned. """ engine = db_api.get_engine() return engine.execute(sql) def copy_data_file(self, file_name, dst_dir): src_file_name = os.path.join('glance/tests/etc', file_name) shutil.copy(src_file_name, dst_dir) dst_file_name = os.path.join(dst_dir, file_name) return dst_file_name def add_log_details(self, servers=None): logs = [s.log_file for s in (servers or self.launched_servers)] for log in logs: if os.path.exists(log): testtools.content.attach_file(self, log) glance-2014.1/glance/tests/functional/v1/0000775000175400017540000000000012323736427021264 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/tests/functional/v1/test_copy_to_file.py0000664000175400017540000002323112323736226025346 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation # 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. """ Tests copying images to a Glance API server which uses a filesystem- based storage backend. """ import hashlib import httplib2 import tempfile import time from six.moves import xrange from glance.openstack.common import jsonutils from glance.openstack.common import units from glance.tests import functional from glance.tests.functional.store_utils import get_http_uri from glance.tests.functional.store_utils import setup_http from glance.tests.utils import skip_if_disabled FIVE_KB = 5 * units.Ki class TestCopyToFile(functional.FunctionalTest): """ Functional tests for copying images from the HTTP storage backend to file """ def _do_test_copy_from(self, from_store, get_uri): """ Ensure we can copy from an external image in from_store. """ self.cleanup() self.start_servers(**self.__dict__.copy()) setup_http(self) # POST /images with public image to be stored in from_store, # to stand in for the 'external' image image_data = "*" * FIVE_KB headers = {'Content-Type': 'application/octet-stream', 'X-Image-Meta-Name': 'external', 'X-Image-Meta-Store': from_store, 'X-Image-Meta-disk_format': 'raw', 'X-Image-Meta-container_format': 'ovf', 'X-Image-Meta-Is-Public': 'True'} path = "http://%s:%d/v1/images" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, 'POST', headers=headers, body=image_data) self.assertEqual(response.status, 201, content) data = jsonutils.loads(content) original_image_id = data['image']['id'] copy_from = get_uri(self, original_image_id) # POST /images with public image copied from_store (to file) headers = {'X-Image-Meta-Name': 'copied', 'X-Image-Meta-disk_format': 'raw', 'X-Image-Meta-container_format': 'ovf', 'X-Image-Meta-Is-Public': 'True', 'X-Glance-API-Copy-From': copy_from} path = "http://%s:%d/v1/images" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, 'POST', headers=headers) self.assertEqual(response.status, 201, content) data = jsonutils.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" % ("127.0.0.1", self.api_port, copy_image_id) def _await_status(expected_status): for i in xrange(100): time.sleep(0.01) http = httplib2.Http() response, content = http.request(path, 'HEAD') self.assertEqual(response.status, 200) if response['x-image-meta-status'] == expected_status: return self.fail('unexpected image status %s' % response['x-image-meta-status']) _await_status('active') http = httplib2.Http() response, content = http.request(path, 'GET') self.assertEqual(response.status, 200) self.assertEqual(response['content-length'], str(FIVE_KB)) self.assertEqual(content, "*" * FIVE_KB) self.assertEqual(hashlib.md5(content).hexdigest(), hashlib.md5("*" * FIVE_KB).hexdigest()) self.assertEqual(data['image']['size'], FIVE_KB) self.assertEqual(data['image']['name'], "copied") # DELETE original image path = "http://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port, original_image_id) http = httplib2.Http() response, content = http.request(path, 'DELETE') self.assertEqual(response.status, 200) # GET image again to make sure the existence of the original # image in from_store is not depended on path = "http://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port, copy_image_id) http = httplib2.Http() response, content = http.request(path, 'GET') self.assertEqual(response.status, 200) self.assertEqual(response['content-length'], str(FIVE_KB)) self.assertEqual(content, "*" * FIVE_KB) self.assertEqual(hashlib.md5(content).hexdigest(), hashlib.md5("*" * FIVE_KB).hexdigest()) self.assertEqual(data['image']['size'], FIVE_KB) self.assertEqual(data['image']['name'], "copied") # DELETE copied image path = "http://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port, copy_image_id) http = httplib2.Http() response, content = http.request(path, 'DELETE') self.assertEqual(response.status, 200) self.stop_servers() @skip_if_disabled def test_copy_from_http_store(self): """ Ensure we can copy from an external image in HTTP store. """ self._do_test_copy_from('file', get_http_uri) @skip_if_disabled def _do_test_copy_from_http(self, exists): """ Ensure we can copy from an external image in HTTP. :param exists: True iff the external source image exists """ self.cleanup() self.start_servers(**self.__dict__.copy()) setup_http(self) uri = get_http_uri(self, 'foobar') copy_from = uri if exists else uri.replace('images', 'snafu') # POST /images with public image copied from HTTP (to file) headers = {'X-Image-Meta-Name': 'copied', 'X-Image-Meta-disk_format': 'raw', 'X-Image-Meta-container_format': 'ovf', 'X-Image-Meta-Is-Public': 'True', 'X-Glance-API-Copy-From': copy_from} path = "http://%s:%d/v1/images" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, 'POST', headers=headers) self.assertEqual(response.status, 201, content) data = jsonutils.loads(content) copy_image_id = data['image']['id'] self.assertEqual(data['image']['status'], 'queued', content) path = "http://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port, copy_image_id) def _await_status(expected_status): for i in xrange(100): time.sleep(0.01) http = httplib2.Http() response, content = http.request(path, 'HEAD') self.assertEqual(response.status, 200) if response['x-image-meta-status'] == expected_status: return self.fail('unexpected image status %s' % response['x-image-meta-status']) _await_status('active' if exists else 'killed') # GET image and make sure image content is as expected http = httplib2.Http() response, content = http.request(path, 'GET') self.assertEqual(response.status, 200 if exists else 404) if exists: self.assertEqual(response['content-length'], str(FIVE_KB)) self.assertEqual(content, "*" * FIVE_KB) self.assertEqual(hashlib.md5(content).hexdigest(), hashlib.md5("*" * FIVE_KB).hexdigest()) # DELETE copied image http = httplib2.Http() response, content = http.request(path, 'DELETE') self.assertEqual(response.status, 200) self.stop_servers() @skip_if_disabled def test_copy_from_http_exists(self): self._do_test_copy_from_http(True) @skip_if_disabled def test_copy_from_http_nonexistent(self): self._do_test_copy_from_http(False) @skip_if_disabled def test_copy_from_file(self): """ Ensure we can't copy from file """ self.cleanup() self.start_servers(**self.__dict__.copy()) with tempfile.NamedTemporaryFile() as image_file: image_file.write("XXX") image_file.flush() copy_from = 'file://' + image_file.name # POST /images with public image copied from file (to file) headers = {'X-Image-Meta-Name': 'copied', 'X-Image-Meta-disk_format': 'raw', 'X-Image-Meta-container_format': 'ovf', 'X-Image-Meta-Is-Public': 'True', 'X-Glance-API-Copy-From': copy_from} path = "http://%s:%d/v1/images" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, 'POST', headers=headers) self.assertEqual(response.status, 400, content) expected = 'External sourcing not supported for store ' + copy_from msg = 'expected "%s" in "%s"' % (expected, content) self.assertTrue(expected in content, msg) self.stop_servers() glance-2014.1/glance/tests/functional/v1/test_misc.py0000664000175400017540000001106012323736226023623 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import hashlib import httplib2 import os from glance.openstack.common import jsonutils from glance.openstack.common import units from glance.tests import functional from glance.tests.utils import execute from glance.tests.utils import minimal_headers FIVE_KB = 5 * units.Ki FIVE_GB = 5 * units.Gi class TestMiscellaneous(functional.FunctionalTest): """Some random tests for various bugs and stuff""" def setUp(self): super(TestMiscellaneous, self).setUp() # NOTE(sirp): This is needed in case we are running the tests under an # environment in which OS_AUTH_STRATEGY=keystone. The test server we # spin up won't have keystone support, so we need to switch to the # NoAuth strategy. os.environ['OS_AUTH_STRATEGY'] = 'noauth' os.environ['OS_AUTH_URL'] = '' def test_api_response_when_image_deleted_from_filesystem(self): """ A test for LP bug #781410 -- glance should fail more gracefully on requests for images that have been removed from the fs """ self.cleanup() self.start_servers() # 1. POST /images with public image named Image1 # attribute and no custom properties. Verify a 200 OK is returned image_data = "*" * FIVE_KB headers = minimal_headers('Image1') path = "http://%s:%d/v1/images" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, 'POST', headers=headers, body=image_data) self.assertEqual(response.status, 201) data = jsonutils.loads(content) self.assertEqual(data['image']['checksum'], hashlib.md5(image_data).hexdigest()) self.assertEqual(data['image']['size'], FIVE_KB) self.assertEqual(data['image']['name'], "Image1") self.assertEqual(data['image']['is_public'], True) # 2. REMOVE the image from the filesystem image_path = "%s/images/%s" % (self.test_dir, data['image']['id']) os.remove(image_path) # 3. HEAD /images/1 # Verify image found now path = "http://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port, data['image']['id']) http = httplib2.Http() response, content = http.request(path, 'HEAD') self.assertEqual(response.status, 200) self.assertEqual(response['x-image-meta-name'], "Image1") # 4. GET /images/1 # Verify the api throws the appropriate 404 error path = "http://%s:%d/v1/images/1" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, 'GET') self.assertEqual(response.status, 404) self.stop_servers() def test_exception_not_eaten_from_registry_to_api(self): """ A test for LP bug #704854 -- Exception thrown by registry server is consumed by API server. We start both servers daemonized. We then use curl to try adding an image that does not meet validation requirements on the registry server and test that the error returned from the API server to curl is appropriate """ self.cleanup() self.start_servers() api_port = self.api_port cmd = "curl -g http://127.0.0.1:%d/v1/images" % api_port exitcode, out, err = execute(cmd) self.assertEqual(0, exitcode) self.assertEqual('{"images": []}', out.strip()) cmd = ("curl -X POST -H 'Content-Type: application/octet-stream' " "-H 'X-Image-Meta-Name: ImageName' " "-H 'X-Image-Meta-Disk-Format: Invalid' " "http://127.0.0.1:%d/v1/images" % api_port) ignored, out, err = execute(cmd) self.assertTrue('Invalid disk format' in out, "Could not find 'Invalid disk format' " "in output: %s" % out) self.stop_servers() glance-2014.1/glance/tests/functional/v1/test_multiprocessing.py0000664000175400017540000000473012323736230026120 0ustar jenkinsjenkins00000000000000# Copyright 2012 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import time import httplib2 import psutil from glance.tests import functional from glance.tests.utils import execute class TestMultiprocessing(functional.FunctionalTest): """Functional tests for the bin/glance CLI tool""" def setUp(self): self.workers = 2 super(TestMultiprocessing, self).setUp() def test_multiprocessing(self): """Spin up the api servers with multiprocessing on""" self.cleanup() self.start_servers(**self.__dict__.copy()) path = "http://%s:%d/v1/images" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, 'GET') self.assertEqual(response.status, 200) self.assertEqual(content, '{"images": []}') self.stop_servers() def _get_children(self): api_pid = self.api_server.process_pid process = psutil.Process(api_pid) children = process.get_children() pids = [str(child.pid) for child in children] return pids def test_interrupt_avoids_respawn_storm(self): """ Ensure an interrupt signal does not cause a respawn storm. See bug #978130 """ self.cleanup() self.start_servers(**self.__dict__.copy()) children = self._get_children() cmd = "kill -INT %s" % ' '.join(children) execute(cmd, raise_error=True) for _ in range(9): # Yeah. This totally isn't a race condition. Randomly fails # set at 0.05. Works most of the time at 0.10 time.sleep(0.10) # ensure number of children hasn't grown self.assertTrue(len(children) >= len(self._get_children())) for child in self._get_children(): # ensure no new children spawned self.assertTrue(child in children, child) self.stop_servers() glance-2014.1/glance/tests/functional/v1/test_api.py0000664000175400017540000005667412323736230023460 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """Functional test case that utilizes httplib2 against the API server""" import hashlib import httplib2 from glance.openstack.common import jsonutils from glance.openstack.common import units from glance.tests import functional from glance.tests.utils import minimal_headers from glance.tests.utils import skip_if_disabled FIVE_KB = 5 * units.Ki FIVE_GB = 5 * units.Gi class TestApi(functional.FunctionalTest): """Functional tests using httplib2 against the API server""" @skip_if_disabled def test_get_head_simple_post(self): """ We test the following sequential series of actions: 0. GET /images - Verify no public images 1. GET /images/detail - Verify no public images 2. POST /images with public image named Image1 and no custom properties - Verify 201 returned 3. HEAD image - Verify HTTP headers have correct information we just added 4. GET image - Verify all information on image we just added is correct 5. GET /images - Verify the image we just added is returned 6. GET /images/detail - Verify the image we just added is returned 7. PUT image with custom properties of "distro" and "arch" - Verify 200 returned 8. PUT image with too many custom properties - Verify 413 returned 9. GET image - Verify updated information about image was stored 10. PUT image - Remove a previously existing property. 11. PUT image - Add a previously deleted property. 12. PUT image/members/member1 - Add member1 to image 13. PUT image/members/member2 - Add member2 to image 14. GET image/members - List image members 15. DELETE image/members/member1 - Delete image member1 16. PUT image/members - Attempt to replace members with an overlimit amount 17. PUT image/members/member11 - Attempt to add a member while at limit 18. POST /images with another public image named Image2 - attribute and three custom properties, "distro", "arch" & "foo" - Verify a 200 OK is returned 19. HEAD image2 - Verify image2 found now 20. GET /images - Verify 2 public images 21. GET /images with filter on user-defined property "distro". - Verify both images are returned 22. GET /images with filter on user-defined property 'distro' but - with non-existent value. Verify no images are returned 23. GET /images with filter on non-existent user-defined property - "boo". Verify no images are returned 24. GET /images with filter 'arch=i386' - Verify only image2 is returned 25. GET /images with filter 'arch=x86_64' - Verify only image1 is returned 26. GET /images with filter 'foo=bar' - Verify only image2 is returned 27. DELETE image1 - Delete image 28. GET image/members - List deleted image members 29. PUT image/members/member2 - Update existing member2 of deleted image 30. PUT image/members/member3 - Add member3 to deleted image 31. DELETE image/members/member2 - Delete member2 from deleted image 32. DELETE image2 - Delete image 33. GET /images - Verify no images are listed """ self.cleanup() self.start_servers(**self.__dict__.copy()) # 0. GET /images # Verify no public images path = "http://%s:%d/v1/images" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, 'GET') self.assertEqual(response.status, 200) self.assertEqual(content, '{"images": []}') # 1. GET /images/detail # Verify no public images path = "http://%s:%d/v1/images/detail" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, 'GET') self.assertEqual(response.status, 200) self.assertEqual(content, '{"images": []}') # 2. POST /images with public image named Image1 # attribute and no custom properties. Verify a 200 OK is returned image_data = "*" * FIVE_KB headers = minimal_headers('Image1') path = "http://%s:%d/v1/images" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, 'POST', headers=headers, body=image_data) self.assertEqual(response.status, 201) data = jsonutils.loads(content) image_id = data['image']['id'] self.assertEqual(data['image']['checksum'], hashlib.md5(image_data).hexdigest()) self.assertEqual(data['image']['size'], FIVE_KB) self.assertEqual(data['image']['name'], "Image1") self.assertEqual(data['image']['is_public'], True) # 3. HEAD image # Verify image found now path = "http://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port, image_id) http = httplib2.Http() response, content = http.request(path, 'HEAD') self.assertEqual(response.status, 200) self.assertEqual(response['x-image-meta-name'], "Image1") # 4. GET image # Verify all information on image we just added is correct path = "http://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port, image_id) http = httplib2.Http() response, content = http.request(path, 'GET') self.assertEqual(response.status, 200) expected_image_headers = { 'x-image-meta-id': image_id, 'x-image-meta-name': 'Image1', 'x-image-meta-is_public': 'True', 'x-image-meta-status': 'active', 'x-image-meta-disk_format': 'raw', 'x-image-meta-container_format': 'ovf', 'x-image-meta-size': str(FIVE_KB)} expected_std_headers = { 'content-length': str(FIVE_KB), 'content-type': 'application/octet-stream'} for expected_key, expected_value in expected_image_headers.items(): self.assertEqual(response[expected_key], expected_value, "For key '%s' expected header value '%s'. " "Got '%s'" % (expected_key, expected_value, response[expected_key])) for expected_key, expected_value in expected_std_headers.items(): self.assertEqual(response[expected_key], expected_value, "For key '%s' expected header value '%s'. " "Got '%s'" % (expected_key, expected_value, response[expected_key])) self.assertEqual(content, "*" * FIVE_KB) self.assertEqual(hashlib.md5(content).hexdigest(), hashlib.md5("*" * FIVE_KB).hexdigest()) # 5. GET /images # Verify one public image path = "http://%s:%d/v1/images" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, 'GET') self.assertEqual(response.status, 200) expected_result = {"images": [ {"container_format": "ovf", "disk_format": "raw", "id": image_id, "name": "Image1", "checksum": "c2e5db72bd7fd153f53ede5da5a06de3", "size": 5120}]} self.assertEqual(jsonutils.loads(content), expected_result) # 6. GET /images/detail # Verify image and all its metadata path = "http://%s:%d/v1/images/detail" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, 'GET') self.assertEqual(response.status, 200) expected_image = { "status": "active", "name": "Image1", "deleted": False, "container_format": "ovf", "disk_format": "raw", "id": image_id, "is_public": True, "deleted_at": None, "properties": {}, "size": 5120} image = jsonutils.loads(content) for expected_key, expected_value in expected_image.items(): self.assertEqual(expected_value, image['images'][0][expected_key], "For key '%s' expected header value '%s'. " "Got '%s'" % (expected_key, expected_value, image['images'][0][expected_key])) # 7. PUT image with custom properties of "distro" and "arch" # Verify 200 returned headers = {'X-Image-Meta-Property-Distro': 'Ubuntu', 'X-Image-Meta-Property-Arch': 'x86_64'} path = "http://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port, image_id) http = httplib2.Http() response, content = http.request(path, 'PUT', headers=headers) self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(data['image']['properties']['arch'], "x86_64") self.assertEqual(data['image']['properties']['distro'], "Ubuntu") # 8. PUT image with too many custom properties # Verify 413 returned headers = {} for i in range(11): # configured limit is 10 headers['X-Image-Meta-Property-foo%d' % i] = 'bar' path = "http://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port, image_id) http = httplib2.Http() response, content = http.request(path, 'PUT', headers=headers) self.assertEqual(response.status, 413) # 9. GET /images/detail # Verify image and all its metadata path = "http://%s:%d/v1/images/detail" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, 'GET') self.assertEqual(response.status, 200) expected_image = { "status": "active", "name": "Image1", "deleted": False, "container_format": "ovf", "disk_format": "raw", "id": image_id, "is_public": True, "deleted_at": None, "properties": {'distro': 'Ubuntu', 'arch': 'x86_64'}, "size": 5120} image = jsonutils.loads(content) for expected_key, expected_value in expected_image.items(): self.assertEqual(expected_value, image['images'][0][expected_key], "For key '%s' expected header value '%s'. " "Got '%s'" % (expected_key, expected_value, image['images'][0][expected_key])) # 10. PUT image and remove a previously existing property. headers = {'X-Image-Meta-Property-Arch': 'x86_64'} path = "http://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port, image_id) http = httplib2.Http() response, content = http.request(path, 'PUT', headers=headers) self.assertEqual(response.status, 200) path = "http://%s:%d/v1/images/detail" % ("127.0.0.1", self.api_port) response, content = http.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content)['images'][0] self.assertEqual(len(data['properties']), 1) self.assertEqual(data['properties']['arch'], "x86_64") # 11. PUT image and add a previously deleted property. headers = {'X-Image-Meta-Property-Distro': 'Ubuntu', 'X-Image-Meta-Property-Arch': 'x86_64'} path = "http://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port, image_id) http = httplib2.Http() response, content = http.request(path, 'PUT', headers=headers) self.assertEqual(response.status, 200) data = jsonutils.loads(content) path = "http://%s:%d/v1/images/detail" % ("127.0.0.1", self.api_port) response, content = http.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content)['images'][0] self.assertEqual(len(data['properties']), 2) self.assertEqual(data['properties']['arch'], "x86_64") self.assertEqual(data['properties']['distro'], "Ubuntu") self.assertNotEqual(data['created_at'], data['updated_at']) # 12. Add member to image path = ("http://%s:%d/v1/images/%s/members/pattieblack" % ("127.0.0.1", self.api_port, image_id)) http = httplib2.Http() response, content = http.request(path, 'PUT') self.assertEqual(response.status, 204) # 13. Add member to image path = ("http://%s:%d/v1/images/%s/members/pattiewhite" % ("127.0.0.1", self.api_port, image_id)) http = httplib2.Http() response, content = http.request(path, 'PUT') self.assertEqual(response.status, 204) # 14. List image members path = ("http://%s:%d/v1/images/%s/members" % ("127.0.0.1", self.api_port, image_id)) http = httplib2.Http() response, content = http.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(len(data['members']), 2) self.assertEqual(data['members'][0]['member_id'], 'pattieblack') self.assertEqual(data['members'][1]['member_id'], 'pattiewhite') # 15. Delete image member path = ("http://%s:%d/v1/images/%s/members/pattieblack" % ("127.0.0.1", self.api_port, image_id)) http = httplib2.Http() response, content = http.request(path, 'DELETE') self.assertEqual(response.status, 204) # 16. Attempt to replace members with an overlimit amount # Adding 11 image members should fail since configured limit is 10 path = ("http://%s:%d/v1/images/%s/members" % ("127.0.0.1", self.api_port, image_id)) memberships = [] for i in range(11): member_id = "foo%d" % i memberships.append(dict(member_id=member_id)) http = httplib2.Http() body = jsonutils.dumps(dict(memberships=memberships)) response, content = http.request(path, 'PUT', body=body) self.assertEqual(response.status, 413) # 17. Attempt to add a member while at limit # Adding an 11th member should fail since configured limit is 10 path = ("http://%s:%d/v1/images/%s/members" % ("127.0.0.1", self.api_port, image_id)) memberships = [] for i in range(10): member_id = "foo%d" % i memberships.append(dict(member_id=member_id)) http = httplib2.Http() body = jsonutils.dumps(dict(memberships=memberships)) response, content = http.request(path, 'PUT', body=body) self.assertEqual(response.status, 204) path = ("http://%s:%d/v1/images/%s/members/fail_me" % ("127.0.0.1", self.api_port, image_id)) http = httplib2.Http() response, content = http.request(path, 'PUT') self.assertEqual(response.status, 413) # 18. POST /images with another public image named Image2 # attribute and three custom properties, "distro", "arch" & "foo". # Verify a 200 OK is returned image_data = "*" * FIVE_KB headers = minimal_headers('Image2') headers['X-Image-Meta-Property-Distro'] = 'Ubuntu' headers['X-Image-Meta-Property-Arch'] = 'i386' headers['X-Image-Meta-Property-foo'] = 'bar' path = "http://%s:%d/v1/images" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, 'POST', headers=headers, body=image_data) self.assertEqual(response.status, 201) data = jsonutils.loads(content) image2_id = data['image']['id'] self.assertEqual(data['image']['checksum'], hashlib.md5(image_data).hexdigest()) self.assertEqual(data['image']['size'], FIVE_KB) self.assertEqual(data['image']['name'], "Image2") self.assertEqual(data['image']['is_public'], True) self.assertEqual(data['image']['properties']['distro'], 'Ubuntu') self.assertEqual(data['image']['properties']['arch'], 'i386') self.assertEqual(data['image']['properties']['foo'], 'bar') # 19. HEAD image2 # Verify image2 found now path = "http://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port, image2_id) http = httplib2.Http() response, content = http.request(path, 'HEAD') self.assertEqual(response.status, 200) self.assertEqual(response['x-image-meta-name'], "Image2") # 20. GET /images # Verify 2 public images path = "http://%s:%d/v1/images" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, 'GET') self.assertEqual(response.status, 200) images = jsonutils.loads(content)['images'] self.assertEqual(len(images), 2) self.assertEqual(images[0]['id'], image2_id) self.assertEqual(images[1]['id'], image_id) # 21. GET /images with filter on user-defined property 'distro'. # Verify both images are returned path = "http://%s:%d/v1/images?property-distro=Ubuntu" % \ ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, 'GET') self.assertEqual(response.status, 200) images = jsonutils.loads(content)['images'] self.assertEqual(len(images), 2) self.assertEqual(images[0]['id'], image2_id) self.assertEqual(images[1]['id'], image_id) # 22. GET /images with filter on user-defined property 'distro' but # with non-existent value. Verify no images are returned path = "http://%s:%d/v1/images?property-distro=fedora" % \ ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, 'GET') self.assertEqual(response.status, 200) images = jsonutils.loads(content)['images'] self.assertEqual(len(images), 0) # 23. GET /images with filter on non-existent user-defined property # 'boo'. Verify no images are returned path = "http://%s:%d/v1/images?property-boo=bar" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, 'GET') self.assertEqual(response.status, 200) images = jsonutils.loads(content)['images'] self.assertEqual(len(images), 0) # 24. GET /images with filter 'arch=i386' # Verify only image2 is returned path = "http://%s:%d/v1/images?property-arch=i386" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, 'GET') self.assertEqual(response.status, 200) images = jsonutils.loads(content)['images'] self.assertEqual(len(images), 1) self.assertEqual(images[0]['id'], image2_id) # 25. GET /images with filter 'arch=x86_64' # Verify only image1 is returned path = "http://%s:%d/v1/images?property-arch=x86_64" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, 'GET') self.assertEqual(response.status, 200) images = jsonutils.loads(content)['images'] self.assertEqual(len(images), 1) self.assertEqual(images[0]['id'], image_id) # 26. GET /images with filter 'foo=bar' # Verify only image2 is returned path = "http://%s:%d/v1/images?property-foo=bar" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, 'GET') self.assertEqual(response.status, 200) images = jsonutils.loads(content)['images'] self.assertEqual(len(images), 1) self.assertEqual(images[0]['id'], image2_id) # 27. DELETE image1 path = "http://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port, image_id) http = httplib2.Http() response, content = http.request(path, 'DELETE') self.assertEqual(response.status, 200) # 28. Try to list members of deleted image path = ("http://%s:%d/v1/images/%s/members" % ("127.0.0.1", self.api_port, image_id)) http = httplib2.Http() response, content = http.request(path, 'GET') self.assertEqual(response.status, 404) # 29. Try to update member of deleted image path = ("http://%s:%d/v1/images/%s/members" % ("127.0.0.1", self.api_port, image_id)) http = httplib2.Http() fixture = [{'member_id': 'pattieblack', 'can_share': 'false'}] body = jsonutils.dumps(dict(memberships=fixture)) response, content = http.request(path, 'PUT', body=body) self.assertEqual(response.status, 404) # 30. Try to add member to deleted image path = ("http://%s:%d/v1/images/%s/members/chickenpattie" % ("127.0.0.1", self.api_port, image_id)) http = httplib2.Http() response, content = http.request(path, 'PUT') self.assertEqual(response.status, 404) # 31. Try to delete member of deleted image path = ("http://%s:%d/v1/images/%s/members/pattieblack" % ("127.0.0.1", self.api_port, image_id)) http = httplib2.Http() response, content = http.request(path, 'DELETE') self.assertEqual(response.status, 404) # 32. DELETE image2 path = "http://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port, image2_id) http = httplib2.Http() response, content = http.request(path, 'DELETE') self.assertEqual(response.status, 200) # 33. GET /images # Verify no images are listed path = "http://%s:%d/v1/images" % ("127.0.0.1", self.api_port) http = httplib2.Http() response, content = http.request(path, 'GET') self.assertEqual(response.status, 200) images = jsonutils.loads(content)['images'] self.assertEqual(len(images), 0) self.stop_servers() glance-2014.1/glance/tests/functional/v1/test_ssl.py0000664000175400017540000015675312323736226023514 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ Tests a Glance API server which uses an Swift backend by default This test requires that a real Swift account is available. It looks in a file GLANCE_TEST_SWIFT_CONF environ variable for the credentials to use. Note that this test clears the entire container from the Swift account for use by the test case, so make sure you supply credentials for test accounts only. If a connection cannot be established, all the test cases are skipped. """ import datetime import hashlib import httplib2 import os import tempfile import uuid from glance.openstack.common import jsonutils from glance.openstack.common import timeutils from glance.openstack.common import units from glance.tests import functional from glance.tests.utils import minimal_headers from glance.tests.utils import skip_if_disabled FIVE_KB = 5 * units.Ki FIVE_GB = 5 * units.Gi TEST_VAR_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), '../..', 'var')) class TestSSL(functional.FunctionalTest): """Functional tests verifying SSL communication""" def setUp(self): super(TestSSL, self).setUp() if getattr(self, 'inited', False): return self.inited = False self.disabled = True # Test key/cert/CA file created as per: # http://blog.didierstevens.com/2008/12/30/ # howto-make-your-own-cert-with-openssl/ # Note that for these tests certificate.crt had to # be created with 'Common Name' set to 127.0.0.1 self.key_file = os.path.join(TEST_VAR_DIR, 'privatekey.key') if not os.path.exists(self.key_file): self.disabled_message = ("Could not find private key file %s" % self.key_file) self.inited = True return self.cert_file = os.path.join(TEST_VAR_DIR, 'certificate.crt') if not os.path.exists(self.cert_file): self.disabled_message = ("Could not find certificate file %s" % self.cert_file) self.inited = True return self.ca_file = os.path.join(TEST_VAR_DIR, 'ca.crt') if not os.path.exists(self.ca_file): self.disabled_message = ("Could not find CA file %s" % self.ca_file) self.inited = True return self.inited = True self.disabled = False def tearDown(self): super(TestSSL, self).tearDown() if getattr(self, 'inited', False): return @skip_if_disabled def test_get_head_simple_post(self): """ We test the following sequential series of actions: 0. GET /images - Verify no public images 1. GET /images/detail - Verify no public images 2. POST /images with public image named Image1 and no custom properties - Verify 201 returned 3. HEAD image - Verify HTTP headers have correct information we just added 4. GET image - Verify all information on image we just added is correct 5. GET /images - Verify the image we just added is returned 6. GET /images/detail - Verify the image we just added is returned 7. PUT image with custom properties of "distro" and "arch" - Verify 200 returned 8. GET image - Verify updated information about image was stored 9. PUT image - Remove a previously existing property. 10. PUT image - Add a previously deleted property. """ self.cleanup() self.start_servers(**self.__dict__.copy()) # 0. GET /images # Verify no public images path = "https://%s:%d/v1/images" % ("127.0.0.1", self.api_port) https = httplib2.Http(disable_ssl_certificate_validation=True) response, content = https.request(path, 'GET') self.assertEqual(response.status, 200) self.assertEqual(content, '{"images": []}') # 1. GET /images/detail # Verify no public images path = "https://%s:%d/v1/images/detail" % ("127.0.0.1", self.api_port) https = httplib2.Http(disable_ssl_certificate_validation=True) response, content = https.request(path, 'GET') self.assertEqual(response.status, 200) self.assertEqual(content, '{"images": []}') # 2. POST /images with public image named Image1 # attribute and no custom properties. Verify a 200 OK is returned image_data = "*" * FIVE_KB headers = minimal_headers('Image1') path = "https://%s:%d/v1/images" % ("127.0.0.1", self.api_port) https = httplib2.Http(disable_ssl_certificate_validation=True) response, content = https.request(path, 'POST', headers=headers, body=image_data) self.assertEqual(response.status, 201) data = jsonutils.loads(content) self.assertEqual(data['image']['checksum'], hashlib.md5(image_data).hexdigest()) self.assertEqual(data['image']['size'], FIVE_KB) self.assertEqual(data['image']['name'], "Image1") self.assertEqual(data['image']['is_public'], True) image_id = data['image']['id'] # 3. HEAD image # Verify image found now path = "https://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port, image_id) https = httplib2.Http(disable_ssl_certificate_validation=True) response, content = https.request(path, 'HEAD') self.assertEqual(response.status, 200) self.assertEqual(response['x-image-meta-name'], "Image1") # 4. GET image # Verify all information on image we just added is correct path = "https://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port, image_id) https = httplib2.Http(disable_ssl_certificate_validation=True) response, content = https.request(path, 'GET') self.assertEqual(response.status, 200) expected_image_headers = { 'x-image-meta-id': image_id, 'x-image-meta-name': 'Image1', 'x-image-meta-is_public': 'True', 'x-image-meta-status': 'active', 'x-image-meta-disk_format': 'raw', 'x-image-meta-container_format': 'ovf', 'x-image-meta-size': str(FIVE_KB)} expected_std_headers = { 'content-length': str(FIVE_KB), 'content-type': 'application/octet-stream'} for expected_key, expected_value in expected_image_headers.items(): self.assertEqual(response[expected_key], expected_value, "For key '%s' expected header value '%s'. " "Got '%s'" % (expected_key, expected_value, response[expected_key])) for expected_key, expected_value in expected_std_headers.items(): self.assertEqual(response[expected_key], expected_value, "For key '%s' expected header value '%s'. " "Got '%s'" % (expected_key, expected_value, response[expected_key])) self.assertEqual(content, "*" * FIVE_KB) self.assertEqual(hashlib.md5(content).hexdigest(), hashlib.md5("*" * FIVE_KB).hexdigest()) # 5. GET /images # Verify no public images path = "https://%s:%d/v1/images" % ("127.0.0.1", self.api_port) https = httplib2.Http(disable_ssl_certificate_validation=True) response, content = https.request(path, 'GET') self.assertEqual(response.status, 200) expected_result = {"images": [ {"container_format": "ovf", "disk_format": "raw", "id": image_id, "name": "Image1", "checksum": "c2e5db72bd7fd153f53ede5da5a06de3", "size": 5120}]} self.assertEqual(jsonutils.loads(content), expected_result) # 6. GET /images/detail # Verify image and all its metadata path = "https://%s:%d/v1/images/detail" % ("127.0.0.1", self.api_port) https = httplib2.Http(disable_ssl_certificate_validation=True) response, content = https.request(path, 'GET') self.assertEqual(response.status, 200) expected_image = { "status": "active", "name": "Image1", "deleted": False, "container_format": "ovf", "disk_format": "raw", "id": image_id, "is_public": True, "deleted_at": None, "properties": {}, "size": 5120} image = jsonutils.loads(content) for expected_key, expected_value in expected_image.items(): self.assertEqual(expected_value, image['images'][0][expected_key], "For key '%s' expected header value '%s'. " "Got '%s'" % (expected_key, expected_value, image['images'][0][expected_key])) # 7. PUT image with custom properties of "distro" and "arch" # Verify 200 returned headers = {'X-Image-Meta-Property-Distro': 'Ubuntu', 'X-Image-Meta-Property-Arch': 'x86_64'} path = "https://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port, image_id) https = httplib2.Http(disable_ssl_certificate_validation=True) response, content = https.request(path, 'PUT', headers=headers) self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(data['image']['properties']['arch'], "x86_64") self.assertEqual(data['image']['properties']['distro'], "Ubuntu") # 8. GET /images/detail # Verify image and all its metadata path = "https://%s:%d/v1/images/detail" % ("127.0.0.1", self.api_port) https = httplib2.Http(disable_ssl_certificate_validation=True) response, content = https.request(path, 'GET') self.assertEqual(response.status, 200) expected_image = { "status": "active", "name": "Image1", "deleted": False, "container_format": "ovf", "disk_format": "raw", "id": image_id, "is_public": True, "deleted_at": None, "properties": {'distro': 'Ubuntu', 'arch': 'x86_64'}, "size": 5120} image = jsonutils.loads(content) for expected_key, expected_value in expected_image.items(): self.assertEqual(expected_value, image['images'][0][expected_key], "For key '%s' expected header value '%s'. " "Got '%s'" % (expected_key, expected_value, image['images'][0][expected_key])) # 9. PUT image and remove a previously existing property. headers = {'X-Image-Meta-Property-Arch': 'x86_64'} path = "https://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port, image_id) https = httplib2.Http(disable_ssl_certificate_validation=True) response, content = https.request(path, 'PUT', headers=headers) self.assertEqual(response.status, 200) path = "https://%s:%d/v1/images/detail" % ("127.0.0.1", self.api_port) response, content = https.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content)['images'][0] self.assertEqual(len(data['properties']), 1) self.assertEqual(data['properties']['arch'], "x86_64") # 10. PUT image and add a previously deleted property. headers = {'X-Image-Meta-Property-Distro': 'Ubuntu', 'X-Image-Meta-Property-Arch': 'x86_64'} path = "https://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port, image_id) https = httplib2.Http(disable_ssl_certificate_validation=True) response, content = https.request(path, 'PUT', headers=headers) self.assertEqual(response.status, 200) data = jsonutils.loads(content) path = "https://%s:%d/v1/images/detail" % ("127.0.0.1", self.api_port) response, content = https.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content)['images'][0] self.assertEqual(len(data['properties']), 2) self.assertEqual(data['properties']['arch'], "x86_64") self.assertEqual(data['properties']['distro'], "Ubuntu") self.stop_servers() @skip_if_disabled def test_queued_process_flow(self): """ We test the process flow where a user registers an image with Glance but does not immediately upload an image file. Later, the user uploads an image file using a PUT operation. We track the changing of image status throughout this process. 0. GET /images - Verify no public images 1. POST /images with public image named Image1 with no location attribute and no image data. - Verify 201 returned 2. GET /images - Verify one public image 3. HEAD image - Verify image now in queued status 4. PUT image with image data - Verify 200 returned 5. HEAD image - Verify image now in active status 6. GET /images - Verify one public image """ self.cleanup() self.start_servers(**self.__dict__.copy()) # 0. GET /images # Verify no public images path = "https://%s:%d/v1/images" % ("127.0.0.1", self.api_port) https = httplib2.Http(disable_ssl_certificate_validation=True) response, content = https.request(path, 'GET') self.assertEqual(response.status, 200) self.assertEqual(content, '{"images": []}') # 1. POST /images with public image named Image1 # with no location or image data headers = minimal_headers('Image1') path = "https://%s:%d/v1/images" % ("127.0.0.1", self.api_port) https = httplib2.Http(disable_ssl_certificate_validation=True) response, content = https.request(path, 'POST', headers=headers) self.assertEqual(response.status, 201) data = jsonutils.loads(content) self.assertIsNone(data['image']['checksum']) self.assertEqual(data['image']['size'], 0) self.assertEqual(data['image']['container_format'], 'ovf') self.assertEqual(data['image']['disk_format'], 'raw') self.assertEqual(data['image']['name'], "Image1") self.assertEqual(data['image']['is_public'], True) image_id = data['image']['id'] # 2. GET /images # Verify 1 public image path = "https://%s:%d/v1/images" % ("127.0.0.1", self.api_port) https = httplib2.Http(disable_ssl_certificate_validation=True) response, content = https.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(data['images'][0]['id'], image_id) self.assertIsNone(data['images'][0]['checksum']) self.assertEqual(data['images'][0]['size'], 0) self.assertEqual(data['images'][0]['container_format'], 'ovf') self.assertEqual(data['images'][0]['disk_format'], 'raw') self.assertEqual(data['images'][0]['name'], "Image1") # 3. HEAD /images # Verify status is in queued path = "https://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port, image_id) https = httplib2.Http(disable_ssl_certificate_validation=True) response, content = https.request(path, 'HEAD') self.assertEqual(response.status, 200) self.assertEqual(response['x-image-meta-name'], "Image1") self.assertEqual(response['x-image-meta-status'], "queued") self.assertEqual(response['x-image-meta-size'], '0') self.assertEqual(response['x-image-meta-id'], image_id) # 4. PUT image with image data, verify 200 returned image_data = "*" * FIVE_KB headers = {'Content-Type': 'application/octet-stream'} path = "https://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port, image_id) https = httplib2.Http(disable_ssl_certificate_validation=True) response, content = https.request(path, 'PUT', headers=headers, body=image_data) self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(data['image']['checksum'], hashlib.md5(image_data).hexdigest()) self.assertEqual(data['image']['size'], FIVE_KB) self.assertEqual(data['image']['name'], "Image1") self.assertEqual(data['image']['is_public'], True) # 5. HEAD image # Verify status is in active path = "https://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port, image_id) https = httplib2.Http(disable_ssl_certificate_validation=True) response, content = https.request(path, 'HEAD') self.assertEqual(response.status, 200) self.assertEqual(response['x-image-meta-name'], "Image1") self.assertEqual(response['x-image-meta-status'], "active") # 6. GET /images # Verify 1 public image still... path = "https://%s:%d/v1/images" % ("127.0.0.1", self.api_port) https = httplib2.Http(disable_ssl_certificate_validation=True) response, content = https.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(data['images'][0]['checksum'], hashlib.md5(image_data).hexdigest()) self.assertEqual(data['images'][0]['id'], image_id) self.assertEqual(data['images'][0]['size'], FIVE_KB) self.assertEqual(data['images'][0]['container_format'], 'ovf') self.assertEqual(data['images'][0]['disk_format'], 'raw') self.assertEqual(data['images'][0]['name'], "Image1") self.stop_servers() @skip_if_disabled def test_version_variations(self): """ We test that various calls to the images and root endpoints are handled properly, and that usage of the Accept: header does content negotiation properly. """ self.cleanup() self.start_servers(**self.__dict__.copy()) versions = {'versions': [{ "id": "v2.2", "status": "CURRENT", "links": [{ "rel": "self", "href": "https://127.0.0.1:%d/v2/" % self.api_port}]}, {"id": "v2.1", "status": "SUPPORTED", "links": [{ "rel": "self", "href": "https://127.0.0.1:%d/v2/" % self.api_port}]}, {"id": "v2.0", "status": "SUPPORTED", "links": [{ "rel": "self", "href": "https://127.0.0.1:%d/v2/" % self.api_port}]}, {"id": "v1.1", "status": "CURRENT", "links": [{ "rel": "self", "href": "https://127.0.0.1:%d/v1/" % self.api_port}]}, {"id": "v1.0", "status": "SUPPORTED", "links": [{ "rel": "self", "href": "https://127.0.0.1:%d/v1/" % self.api_port}]}]} versions_json = jsonutils.dumps(versions) images = {'images': []} images_json = jsonutils.dumps(images) # 0. GET / with no Accept: header # Verify version choices returned. # Bug lp:803260 no Accept header causes a 500 in glance-api path = "https://%s:%d/" % ("127.0.0.1", self.api_port) https = httplib2.Http(disable_ssl_certificate_validation=True) response, content = https.request(path, 'GET') self.assertEqual(response.status, 300) self.assertEqual(content, versions_json) # 1. GET /images with no Accept: header # Verify version choices returned. path = "https://%s:%d/images" % ("127.0.0.1", self.api_port) https = httplib2.Http(disable_ssl_certificate_validation=True) response, content = https.request(path, 'GET') self.assertEqual(response.status, 300) self.assertEqual(content, versions_json) # 2. GET /v1/images with no Accept: header # Verify empty images list returned. path = "https://%s:%d/v1/images" % ("127.0.0.1", self.api_port) https = httplib2.Http(disable_ssl_certificate_validation=True) response, content = https.request(path, 'GET') self.assertEqual(response.status, 200) self.assertEqual(content, images_json) # 3. GET / with Accept: unknown header # Verify version choices returned. Verify message in API log about # unknown accept header. path = "https://%s:%d/" % ("127.0.0.1", self.api_port) https = httplib2.Http(disable_ssl_certificate_validation=True) headers = {'Accept': 'unknown'} response, content = https.request(path, 'GET', headers=headers) self.assertEqual(response.status, 300) self.assertEqual(content, versions_json) self.assertTrue('Unknown version. Returning version choices' in open(self.api_server.log_file).read()) # 4. GET / with an Accept: application/vnd.openstack.images-v1 # Verify empty image list returned path = "https://%s:%d/images" % ("127.0.0.1", self.api_port) https = httplib2.Http(disable_ssl_certificate_validation=True) headers = {'Accept': 'application/vnd.openstack.images-v1'} response, content = https.request(path, 'GET', headers=headers) self.assertEqual(response.status, 200) self.assertEqual(content, images_json) # 5. GET /images with a Accept: application/vnd.openstack.compute-v1 # header. Verify version choices returned. Verify message in API log # about unknown accept header. path = "https://%s:%d/images" % ("127.0.0.1", self.api_port) https = httplib2.Http(disable_ssl_certificate_validation=True) headers = {'Accept': 'application/vnd.openstack.compute-v1'} response, content = https.request(path, 'GET', headers=headers) self.assertEqual(response.status, 300) self.assertEqual(content, versions_json) self.assertTrue('Unknown version. Returning version choices' in open(self.api_server.log_file).read()) # 6. GET /v1.0/images with no Accept: header # Verify empty image list returned path = "https://%s:%d/v1.0/images" % ("127.0.0.1", self.api_port) https = httplib2.Http(disable_ssl_certificate_validation=True) response, content = https.request(path, 'GET') self.assertEqual(response.status, 200) self.assertEqual(content, images_json) # 7. GET /v1.a/images with no Accept: header # Verify versions list returned path = "https://%s:%d/v1.a/images" % ("127.0.0.1", self.api_port) https = httplib2.Http(disable_ssl_certificate_validation=True) response, content = https.request(path, 'GET') self.assertEqual(response.status, 300) self.assertEqual(content, versions_json) # 8. GET /va.1/images with no Accept: header # Verify version choices returned path = "https://%s:%d/va.1/images" % ("127.0.0.1", self.api_port) https = httplib2.Http(disable_ssl_certificate_validation=True) response, content = https.request(path, 'GET') self.assertEqual(response.status, 300) self.assertEqual(content, versions_json) # 9. GET /versions with no Accept: header # Verify version choices returned path = "https://%s:%d/versions" % ("127.0.0.1", self.api_port) https = httplib2.Http(disable_ssl_certificate_validation=True) response, content = https.request(path, 'GET') self.assertEqual(response.status, 300) self.assertEqual(content, versions_json) # 10. GET /versions with a Accept: application/vnd.openstack.images-v1 # header. Verify version choices returned. path = "https://%s:%d/versions" % ("127.0.0.1", self.api_port) https = httplib2.Http(disable_ssl_certificate_validation=True) headers = {'Accept': 'application/vnd.openstack.images-v1'} response, content = https.request(path, 'GET', headers=headers) self.assertEqual(response.status, 300) self.assertEqual(content, versions_json) # 11. GET /v1/versions with no Accept: header # Verify 404 returned path = "https://%s:%d/v1/versions" % ("127.0.0.1", self.api_port) https = httplib2.Http(disable_ssl_certificate_validation=True) response, content = https.request(path, 'GET') self.assertEqual(response.status, 404) # 12. GET /v2/versions with no Accept: header # Verify version choices returned path = "https://%s:%d/v2/versions" % ("127.0.0.1", self.api_port) https = httplib2.Http(disable_ssl_certificate_validation=True) response, content = https.request(path, 'GET') self.assertEqual(response.status, 404) # 12b. GET /v3/versions with no Accept: header (where v3 in unknown) # Verify version choices returned path = "https://%s:%d/v3/versions" % ("127.0.0.1", self.api_port) https = httplib2.Http(disable_ssl_certificate_validation=True) response, content = https.request(path, 'GET') self.assertEqual(response.status, 300) self.assertEqual(content, versions_json) # 13. GET /images with a Accept: application/vnd.openstack.compute-v3 # header. Verify version choices returned. Verify message in API log # about unknown version in accept header. path = "https://%s:%d/images" % ("127.0.0.1", self.api_port) https = httplib2.Http(disable_ssl_certificate_validation=True) headers = {'Accept': 'application/vnd.openstack.images-v3'} response, content = https.request(path, 'GET', headers=headers) self.assertEqual(response.status, 300) self.assertEqual(content, versions_json) self.assertTrue('Unknown version. Returning version choices' in open(self.api_server.log_file).read()) # 14. GET /v1.2/images with no Accept: header # Verify version choices returned path = "https://%s:%d/v1.2/images" % ("127.0.0.1", self.api_port) https = httplib2.Http(disable_ssl_certificate_validation=True) response, content = https.request(path, 'GET') self.assertEqual(response.status, 300) self.assertEqual(content, versions_json) self.stop_servers() @skip_if_disabled def test_size_greater_2G_mysql(self): """ A test against the actual datastore backend for the registry to ensure that the image size property is not truncated. :see https://bugs.launchpad.net/glance/+bug/739433 """ self.cleanup() self.start_servers(**self.__dict__.copy()) # 1. POST /images with public image named Image1 # attribute and a size of 5G. Use the HTTP engine with an # X-Image-Meta-Location attribute to make Glance forego # "adding" the image data. # Verify a 201 OK is returned headers = minimal_headers('Image1') headers['X-Image-Meta-Location'] = 'https://example.com/fakeimage' headers['X-Image-Meta-Size'] = str(FIVE_GB) path = "https://%s:%d/v1/images" % ("127.0.0.1", self.api_port) https = httplib2.Http(disable_ssl_certificate_validation=True) response, content = https.request(path, 'POST', headers=headers) self.assertEqual(response.status, 201) # 2. HEAD /images # Verify image size is what was passed in, and not truncated path = response.get('location') https = httplib2.Http(disable_ssl_certificate_validation=True) response, content = https.request(path, 'HEAD') self.assertEqual(response.status, 200) self.assertEqual(response['x-image-meta-size'], str(FIVE_GB)) self.assertEqual(response['x-image-meta-name'], 'Image1') self.assertEqual(response['x-image-meta-is_public'], 'True') self.stop_servers() @skip_if_disabled def test_traceback_not_consumed(self): """ A test that errors coming from the POST API do not get consumed and print the actual error message, and not something like <traceback object at 0x1918d40> :see https://bugs.launchpad.net/glance/+bug/755912 """ self.cleanup() self.start_servers(**self.__dict__.copy()) # POST /images with binary data, but not setting # Content-Type to application/octet-stream, verify a # 400 returned and that the error is readable. with tempfile.NamedTemporaryFile() as test_data_file: test_data_file.write("XXX") test_data_file.flush() headers = {'X-Image-Meta-Name': 'Image1', 'X-Image-Meta-Container-Format': 'ovf', 'X-Image-Meta-Disk-Format': 'vdi'} path = "https://%s:%d/v1/images" % ("127.0.0.1", self.api_port) https = httplib2.Http(disable_ssl_certificate_validation=True) response, content = https.request(path, 'POST', headers=headers, body=test_data_file.name) self.assertEqual(response.status, 400) expected = "Content-Type must be application/octet-stream" self.assertTrue(expected in content, "Could not find '%s' in '%s'" % (expected, content)) self.stop_servers() @skip_if_disabled def test_filtered_images(self): """ Set up four test images and ensure each query param filter works """ self.cleanup() self.start_servers(**self.__dict__.copy()) # 0. GET /images # Verify no public images path = "https://%s:%d/v1/images" % ("127.0.0.1", self.api_port) https = httplib2.Http(disable_ssl_certificate_validation=True) response, content = https.request(path, 'GET') self.assertEqual(response.status, 200) self.assertEqual(content, '{"images": []}') # 1. POST /images with three public images, and one private image # with various attributes headers = {'Content-Type': 'application/octet-stream', 'X-Image-Meta-Name': 'Image1', 'X-Image-Meta-Status': 'active', 'X-Image-Meta-Container-Format': 'ovf', 'X-Image-Meta-Disk-Format': 'vdi', 'X-Image-Meta-Size': '19', 'X-Image-Meta-Is-Public': 'True', 'X-Image-Meta-Property-pants': 'are on'} path = "https://%s:%d/v1/images" % ("127.0.0.1", self.api_port) https = httplib2.Http(disable_ssl_certificate_validation=True) response, content = https.request(path, 'POST', headers=headers) self.assertEqual(response.status, 201) data = jsonutils.loads(content) self.assertEqual(data['image']['properties']['pants'], "are on") self.assertEqual(data['image']['is_public'], True) headers = {'Content-Type': 'application/octet-stream', 'X-Image-Meta-Name': 'My Image!', 'X-Image-Meta-Status': 'active', 'X-Image-Meta-Container-Format': 'ovf', 'X-Image-Meta-Disk-Format': 'vhd', 'X-Image-Meta-Size': '20', 'X-Image-Meta-Is-Public': 'True', 'X-Image-Meta-Property-pants': 'are on'} path = "https://%s:%d/v1/images" % ("127.0.0.1", self.api_port) https = httplib2.Http(disable_ssl_certificate_validation=True) response, content = https.request(path, 'POST', headers=headers) self.assertEqual(response.status, 201) data = jsonutils.loads(content) self.assertEqual(data['image']['properties']['pants'], "are on") self.assertEqual(data['image']['is_public'], True) headers = {'Content-Type': 'application/octet-stream', 'X-Image-Meta-Name': 'My Image!', 'X-Image-Meta-Status': 'saving', 'X-Image-Meta-Container-Format': 'ami', 'X-Image-Meta-Disk-Format': 'ami', 'X-Image-Meta-Size': '21', 'X-Image-Meta-Is-Public': 'True', 'X-Image-Meta-Property-pants': 'are off'} path = "https://%s:%d/v1/images" % ("127.0.0.1", self.api_port) https = httplib2.Http(disable_ssl_certificate_validation=True) response, content = https.request(path, 'POST', headers=headers) self.assertEqual(response.status, 201) data = jsonutils.loads(content) self.assertEqual(data['image']['properties']['pants'], "are off") self.assertEqual(data['image']['is_public'], True) headers = {'Content-Type': 'application/octet-stream', 'X-Image-Meta-Name': 'My Private Image', 'X-Image-Meta-Status': 'active', 'X-Image-Meta-Container-Format': 'ami', 'X-Image-Meta-Disk-Format': 'ami', 'X-Image-Meta-Size': '22', 'X-Image-Meta-Is-Public': 'False'} path = "https://%s:%d/v1/images" % ("127.0.0.1", self.api_port) https = httplib2.Http(disable_ssl_certificate_validation=True) response, content = https.request(path, 'POST', headers=headers) self.assertEqual(response.status, 201) data = jsonutils.loads(content) self.assertEqual(data['image']['is_public'], False) # 2. GET /images # Verify three public images path = "https://%s:%d/v1/images" % ("127.0.0.1", self.api_port) response, content = https.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(len(data['images']), 3) # 3. GET /images with name filter # Verify correct images returned with name params = "name=My%20Image!" path = "https://%s:%d/v1/images?%s" % ( "127.0.0.1", self.api_port, params) response, content = https.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(len(data['images']), 2) for image in data['images']: self.assertEqual(image['name'], "My Image!") # 4. GET /images with status filter # Verify correct images returned with status params = "status=queued" path = "https://%s:%d/v1/images/detail?%s" % ( "127.0.0.1", self.api_port, params) response, content = https.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(len(data['images']), 3) for image in data['images']: self.assertEqual(image['status'], "queued") params = "status=active" path = "https://%s:%d/v1/images/detail?%s" % ( "127.0.0.1", self.api_port, params) response, content = https.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(len(data['images']), 0) # 5. GET /images with container_format filter # Verify correct images returned with container_format params = "container_format=ovf" path = "https://%s:%d/v1/images?%s" % ( "127.0.0.1", self.api_port, params) response, content = https.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(len(data['images']), 2) for image in data['images']: self.assertEqual(image['container_format'], "ovf") # 6. GET /images with disk_format filter # Verify correct images returned with disk_format params = "disk_format=vdi" path = "https://%s:%d/v1/images?%s" % ( "127.0.0.1", self.api_port, params) response, content = https.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(len(data['images']), 1) for image in data['images']: self.assertEqual(image['disk_format'], "vdi") # 7. GET /images with size_max filter # Verify correct images returned with size <= expected params = "size_max=20" path = "https://%s:%d/v1/images?%s" % ( "127.0.0.1", self.api_port, params) response, content = https.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(len(data['images']), 2) for image in data['images']: self.assertTrue(image['size'] <= 20) # 8. GET /images with size_min filter # Verify correct images returned with size >= expected params = "size_min=20" path = "https://%s:%d/v1/images?%s" % ( "127.0.0.1", self.api_port, params) response, content = https.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(len(data['images']), 2) for image in data['images']: self.assertTrue(image['size'] >= 20) # 9. Get /images with is_public=None filter # Verify correct images returned with property # Bug lp:803656 Support is_public in filtering params = "is_public=None" path = "https://%s:%d/v1/images?%s" % ( "127.0.0.1", self.api_port, params) response, content = https.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(len(data['images']), 4) # 10. Get /images with is_public=False filter # Verify correct images returned with property # Bug lp:803656 Support is_public in filtering params = "is_public=False" path = "https://%s:%d/v1/images?%s" % ( "127.0.0.1", self.api_port, params) response, content = https.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(len(data['images']), 1) for image in data['images']: self.assertEqual(image['name'], "My Private Image") # 11. Get /images with is_public=True filter # Verify correct images returned with property # Bug lp:803656 Support is_public in filtering params = "is_public=True" path = "https://%s:%d/v1/images?%s" % ( "127.0.0.1", self.api_port, params) response, content = https.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(len(data['images']), 3) for image in data['images']: self.assertNotEqual(image['name'], "My Private Image") # 12. GET /images with property filter # Verify correct images returned with property params = "property-pants=are%20on" path = "https://%s:%d/v1/images/detail?%s" % ( "127.0.0.1", self.api_port, params) response, content = https.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(len(data['images']), 2) for image in data['images']: self.assertEqual(image['properties']['pants'], "are on") # 13. GET /images with property filter and name filter # Verify correct images returned with property and name # Make sure you quote the url when using more than one param! params = "name=My%20Image!&property-pants=are%20on" path = "https://%s:%d/v1/images/detail?%s" % ( "127.0.0.1", self.api_port, params) response, content = https.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(len(data['images']), 1) for image in data['images']: self.assertEqual(image['properties']['pants'], "are on") self.assertEqual(image['name'], "My Image!") # 14. GET /images with past changes-since filter dt1 = timeutils.utcnow() - datetime.timedelta(1) iso1 = timeutils.isotime(dt1) params = "changes-since=%s" % iso1 path = "https://%s:%d/v1/images?%s" % ("127.0.0.1", self.api_port, params) response, content = https.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(len(data['images']), 3) # 15. GET /images with future changes-since filter dt2 = timeutils.utcnow() + datetime.timedelta(1) iso2 = timeutils.isotime(dt2) params = "changes-since=%s" % iso2 path = "https://%s:%d/v1/images?%s" % ("127.0.0.1", self.api_port, params) response, content = https.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(len(data['images']), 0) self.stop_servers() @skip_if_disabled def test_limited_images(self): """ Ensure marker and limit query params work """ self.cleanup() self.start_servers(**self.__dict__.copy()) # 0. GET /images # Verify no public images path = "https://%s:%d/v1/images" % ("127.0.0.1", self.api_port) https = httplib2.Http(disable_ssl_certificate_validation=True) response, content = https.request(path, 'GET') self.assertEqual(response.status, 200) self.assertEqual(content, '{"images": []}') # 1. POST /images with three public images with various attributes headers = minimal_headers('Image1') path = "https://%s:%d/v1/images" % ("127.0.0.1", self.api_port) https = httplib2.Http(disable_ssl_certificate_validation=True) response, content = https.request(path, 'POST', headers=headers) self.assertEqual(response.status, 201) data = jsonutils.loads(content) image_ids = [data['image']['id']] headers = minimal_headers('Image2') path = "https://%s:%d/v1/images" % ("127.0.0.1", self.api_port) https = httplib2.Http(disable_ssl_certificate_validation=True) response, content = https.request(path, 'POST', headers=headers) self.assertEqual(response.status, 201) data = jsonutils.loads(content) image_ids.append(data['image']['id']) headers = minimal_headers('Image3') path = "https://%s:%d/v1/images" % ("127.0.0.1", self.api_port) https = httplib2.Http(disable_ssl_certificate_validation=True) response, content = https.request(path, 'POST', headers=headers) self.assertEqual(response.status, 201) data = jsonutils.loads(content) image_ids.append(data['image']['id']) # 2. GET /images with limit of 2 # Verify only two images were returned params = "limit=2" path = "https://%s:%d/v1/images?%s" % ( "127.0.0.1", self.api_port, params) response, content = https.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(len(data['images']), 2) self.assertEqual(data['images'][0]['id'], image_ids[2]) self.assertEqual(data['images'][1]['id'], image_ids[1]) # 3. GET /images with marker # Verify only two images were returned params = "marker=%s" % image_ids[2] path = "https://%s:%d/v1/images?%s" % ( "127.0.0.1", self.api_port, params) response, content = https.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(len(data['images']), 2) self.assertEqual(data['images'][0]['id'], image_ids[1]) self.assertEqual(data['images'][1]['id'], image_ids[0]) # 4. GET /images with marker and limit # Verify only one image was returned with the correct id params = "limit=1&marker=%s" % image_ids[1] path = "https://%s:%d/v1/images?%s" % ( "127.0.0.1", self.api_port, params) response, content = https.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(len(data['images']), 1) self.assertEqual(data['images'][0]['id'], image_ids[0]) # 5. GET /images/detail with marker and limit # Verify only one image was returned with the correct id params = "limit=1&marker=%s" % image_ids[2] path = "https://%s:%d/v1/images?%s" % ( "127.0.0.1", self.api_port, params) response, content = https.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(len(data['images']), 1) self.assertEqual(data['images'][0]['id'], image_ids[1]) self.stop_servers() @skip_if_disabled def test_ordered_images(self): """ Set up three test images and ensure each query param filter works """ self.cleanup() self.start_servers(**self.__dict__.copy()) # 0. GET /images # Verify no public images path = "https://%s:%d/v1/images" % ("127.0.0.1", self.api_port) https = httplib2.Http(disable_ssl_certificate_validation=True) response, content = https.request(path, 'GET') self.assertEqual(response.status, 200) self.assertEqual(content, '{"images": []}') # 1. POST /images with three public images with various attributes headers = {'Content-Type': 'application/octet-stream', 'X-Image-Meta-Name': 'Image1', 'X-Image-Meta-Status': 'active', 'X-Image-Meta-Container-Format': 'ovf', 'X-Image-Meta-Disk-Format': 'vdi', 'X-Image-Meta-Size': '19', 'X-Image-Meta-Is-Public': 'True'} path = "https://%s:%d/v1/images" % ("127.0.0.1", self.api_port) https = httplib2.Http(disable_ssl_certificate_validation=True) response, content = https.request(path, 'POST', headers=headers) self.assertEqual(response.status, 201) data = jsonutils.loads(content) image_ids = [data['image']['id']] headers = {'Content-Type': 'application/octet-stream', 'X-Image-Meta-Name': 'ASDF', 'X-Image-Meta-Status': 'active', 'X-Image-Meta-Container-Format': 'bare', 'X-Image-Meta-Disk-Format': 'iso', 'X-Image-Meta-Size': '2', 'X-Image-Meta-Is-Public': 'True'} path = "https://%s:%d/v1/images" % ("127.0.0.1", self.api_port) https = httplib2.Http(disable_ssl_certificate_validation=True) response, content = https.request(path, 'POST', headers=headers) self.assertEqual(response.status, 201) data = jsonutils.loads(content) image_ids.append(data['image']['id']) headers = {'Content-Type': 'application/octet-stream', 'X-Image-Meta-Name': 'XYZ', 'X-Image-Meta-Status': 'saving', 'X-Image-Meta-Container-Format': 'ami', 'X-Image-Meta-Disk-Format': 'ami', 'X-Image-Meta-Size': '5', 'X-Image-Meta-Is-Public': 'True'} path = "https://%s:%d/v1/images" % ("127.0.0.1", self.api_port) https = httplib2.Http(disable_ssl_certificate_validation=True) response, content = https.request(path, 'POST', headers=headers) self.assertEqual(response.status, 201) data = jsonutils.loads(content) image_ids.append(data['image']['id']) # 2. GET /images with no query params # Verify three public images sorted by created_at desc path = "https://%s:%d/v1/images" % ("127.0.0.1", self.api_port) https = httplib2.Http(disable_ssl_certificate_validation=True) response, content = https.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(len(data['images']), 3) self.assertEqual(data['images'][0]['id'], image_ids[2]) self.assertEqual(data['images'][1]['id'], image_ids[1]) self.assertEqual(data['images'][2]['id'], image_ids[0]) # 3. GET /images sorted by name asc params = 'sort_key=name&sort_dir=asc' path = "https://%s:%d/v1/images?%s" % ("127.0.0.1", self.api_port, params) https = httplib2.Http(disable_ssl_certificate_validation=True) response, content = https.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(len(data['images']), 3) self.assertEqual(data['images'][0]['id'], image_ids[1]) self.assertEqual(data['images'][1]['id'], image_ids[0]) self.assertEqual(data['images'][2]['id'], image_ids[2]) # 4. GET /images sorted by size desc params = 'sort_key=size&sort_dir=desc' path = "https://%s:%d/v1/images?%s" % ("127.0.0.1", self.api_port, params) https = httplib2.Http(disable_ssl_certificate_validation=True) response, content = https.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(len(data['images']), 3) self.assertEqual(data['images'][0]['id'], image_ids[0]) self.assertEqual(data['images'][1]['id'], image_ids[2]) self.assertEqual(data['images'][2]['id'], image_ids[1]) # 5. GET /images sorted by size desc with a marker params = 'sort_key=size&sort_dir=desc&marker=%s' % image_ids[0] path = "https://%s:%d/v1/images?%s" % ("127.0.0.1", self.api_port, params) https = httplib2.Http(disable_ssl_certificate_validation=True) response, content = https.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(len(data['images']), 2) self.assertEqual(data['images'][0]['id'], image_ids[2]) self.assertEqual(data['images'][1]['id'], image_ids[1]) # 6. GET /images sorted by name asc with a marker params = 'sort_key=name&sort_dir=asc&marker=%s' % image_ids[2] path = "https://%s:%d/v1/images?%s" % ("127.0.0.1", self.api_port, params) https = httplib2.Http(disable_ssl_certificate_validation=True) response, content = https.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(len(data['images']), 0) self.stop_servers() @skip_if_disabled def test_duplicate_image_upload(self): """ Upload initial image, then attempt to upload duplicate image """ self.cleanup() self.start_servers(**self.__dict__.copy()) # 0. GET /images # Verify no public images path = "https://%s:%d/v1/images" % ("127.0.0.1", self.api_port) https = httplib2.Http(disable_ssl_certificate_validation=True) response, content = https.request(path, 'GET') self.assertEqual(response.status, 200) self.assertEqual(content, '{"images": []}') # 1. POST /images with public image named Image1 headers = {'Content-Type': 'application/octet-stream', 'X-Image-Meta-Name': 'Image1', 'X-Image-Meta-Status': 'active', 'X-Image-Meta-Container-Format': 'ovf', 'X-Image-Meta-Disk-Format': 'vdi', 'X-Image-Meta-Size': '19', 'X-Image-Meta-Is-Public': 'True'} path = "https://%s:%d/v1/images" % ("127.0.0.1", self.api_port) https = httplib2.Http(disable_ssl_certificate_validation=True) response, content = https.request(path, 'POST', headers=headers) self.assertEqual(response.status, 201) data = jsonutils.loads(content) image_id = data['image']['id'] # 2. POST /images with public image named Image1, and ID: 1 headers = {'Content-Type': 'application/octet-stream', 'X-Image-Meta-Name': 'Image1 Update', 'X-Image-Meta-Status': 'active', 'X-Image-Meta-Container-Format': 'ovf', 'X-Image-Meta-Disk-Format': 'vdi', 'X-Image-Meta-Size': '19', 'X-Image-Meta-Id': image_id, 'X-Image-Meta-Is-Public': 'True'} path = "https://%s:%d/v1/images" % ("127.0.0.1", self.api_port) https = httplib2.Http(disable_ssl_certificate_validation=True) response, content = https.request(path, 'POST', headers=headers) self.assertEqual(response.status, 409) expected = "An image with identifier %s already exists" % image_id self.assertTrue(expected in content, "Could not find '%s' in '%s'" % (expected, content)) self.stop_servers() @skip_if_disabled def test_delete_not_existing(self): """ We test the following: 0. GET /images - Verify no public images 1. DELETE random image - Verify 404 """ self.cleanup() self.start_servers(**self.__dict__.copy()) # 0. GET /images # Verify no public images path = "https://%s:%d/v1/images" % ("127.0.0.1", self.api_port) https = httplib2.Http(disable_ssl_certificate_validation=True) response, content = https.request(path, 'GET') self.assertEqual(response.status, 200) self.assertEqual(content, '{"images": []}') # 1. DELETE /images/1 # Verify 404 returned path = "https://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port, str(uuid.uuid4())) https = httplib2.Http(disable_ssl_certificate_validation=True) response, content = https.request(path, 'DELETE') self.assertEqual(response.status, 404) self.stop_servers() glance-2014.1/glance/tests/functional/v1/__init__.py0000664000175400017540000000000012323736226023360 0ustar jenkinsjenkins00000000000000glance-2014.1/glance/tests/integration/0000775000175400017540000000000012323736427021117 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/tests/integration/legacy_functional/0000775000175400017540000000000012323736427024605 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/tests/integration/legacy_functional/test_v1_api.py0000664000175400017540000022130612323736226027376 0ustar jenkinsjenkins00000000000000# 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 datetime import hashlib import os import tempfile import testtools from glance.openstack.common import jsonutils from glance.openstack.common import timeutils from glance.openstack.common import units from glance.tests.integration.legacy_functional import base from glance.tests.utils import minimal_headers FIVE_KB = 5 * units.Ki FIVE_GB = 5 * units.Gi class TestApi(base.ApiTest): def test_get_head_simple_post(self): # 0. GET /images # Verify no public images path = "/v1/images" response, content = self.http.request(path, 'GET') self.assertEqual(response.status, 200) self.assertEqual(content, '{"images": []}') # 1. GET /images/detail # Verify no public images path = "/v1/images/detail" response, content = self.http.request(path, 'GET') self.assertEqual(response.status, 200) self.assertEqual(content, '{"images": []}') # 2. POST /images with public image named Image1 # attribute and no custom properties. Verify a 200 OK is returned image_data = "*" * FIVE_KB headers = minimal_headers('Image1') path = "/v1/images" response, content = self.http.request(path, 'POST', headers=headers, body=image_data) self.assertEqual(response.status, 201) data = jsonutils.loads(content) image_id = data['image']['id'] self.assertEqual(data['image']['checksum'], hashlib.md5(image_data).hexdigest()) self.assertEqual(data['image']['size'], FIVE_KB) self.assertEqual(data['image']['name'], "Image1") self.assertEqual(data['image']['is_public'], True) # 3. HEAD image # Verify image found now path = "/v1/images/%s" % image_id response, content = self.http.request(path, 'HEAD') self.assertEqual(response.status, 200) self.assertEqual(response['x-image-meta-name'], "Image1") # 4. GET image # Verify all information on image we just added is correct path = "/v1/images/%s" % image_id response, content = self.http.request(path, 'GET') self.assertEqual(response.status, 200) expected_image_headers = { 'x-image-meta-id': image_id, 'x-image-meta-name': 'Image1', 'x-image-meta-is_public': 'True', 'x-image-meta-status': 'active', 'x-image-meta-disk_format': 'raw', 'x-image-meta-container_format': 'ovf', 'x-image-meta-size': str(FIVE_KB)} expected_std_headers = { 'content-length': str(FIVE_KB), 'content-type': 'application/octet-stream'} for expected_key, expected_value in expected_image_headers.items(): self.assertEqual(response[expected_key], expected_value, "For key '%s' expected header value '%s'. " "Got '%s'" % (expected_key, expected_value, response[expected_key])) for expected_key, expected_value in expected_std_headers.items(): self.assertEqual(response[expected_key], expected_value, "For key '%s' expected header value '%s'. " "Got '%s'" % (expected_key, expected_value, response[expected_key])) self.assertEqual(content, "*" * FIVE_KB) self.assertEqual(hashlib.md5(content).hexdigest(), hashlib.md5("*" * FIVE_KB).hexdigest()) # 5. GET /images # Verify no public images path = "/v1/images" response, content = self.http.request(path, 'GET') self.assertEqual(response.status, 200) expected_result = {"images": [ {"container_format": "ovf", "disk_format": "raw", "id": image_id, "name": "Image1", "checksum": "c2e5db72bd7fd153f53ede5da5a06de3", "size": 5120}]} self.assertEqual(jsonutils.loads(content), expected_result) # 6. GET /images/detail # Verify image and all its metadata path = "/v1/images/detail" response, content = self.http.request(path, 'GET') self.assertEqual(response.status, 200) expected_image = { "status": "active", "name": "Image1", "deleted": False, "container_format": "ovf", "disk_format": "raw", "id": image_id, "is_public": True, "deleted_at": None, "properties": {}, "size": 5120} image = jsonutils.loads(content) for expected_key, expected_value in expected_image.items(): self.assertEqual(expected_value, image['images'][0][expected_key], "For key '%s' expected header value '%s'. " "Got '%s'" % (expected_key, expected_value, image['images'][0][expected_key])) # 7. PUT image with custom properties of "distro" and "arch" # Verify 200 returned headers = {'X-Image-Meta-Property-Distro': 'Ubuntu', 'X-Image-Meta-Property-Arch': 'x86_64'} path = "/v1/images/%s" % image_id response, content = self.http.request(path, 'PUT', headers=headers) self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(data['image']['properties']['arch'], "x86_64") self.assertEqual(data['image']['properties']['distro'], "Ubuntu") # 8. GET /images/detail # Verify image and all its metadata path = "/v1/images/detail" response, content = self.http.request(path, 'GET') self.assertEqual(response.status, 200) expected_image = { "status": "active", "name": "Image1", "deleted": False, "container_format": "ovf", "disk_format": "raw", "id": image_id, "is_public": True, "deleted_at": None, "properties": {'distro': 'Ubuntu', 'arch': 'x86_64'}, "size": 5120} image = jsonutils.loads(content) for expected_key, expected_value in expected_image.items(): self.assertEqual(expected_value, image['images'][0][expected_key], "For key '%s' expected header value '%s'. " "Got '%s'" % (expected_key, expected_value, image['images'][0][expected_key])) # 9. PUT image and remove a previously existing property. headers = {'X-Image-Meta-Property-Arch': 'x86_64'} path = "/v1/images/%s" % image_id response, content = self.http.request(path, 'PUT', headers=headers) self.assertEqual(response.status, 200) path = "/v1/images/detail" response, content = self.http.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content)['images'][0] self.assertEqual(len(data['properties']), 1) self.assertEqual(data['properties']['arch'], "x86_64") # 10. PUT image and add a previously deleted property. headers = {'X-Image-Meta-Property-Distro': 'Ubuntu', 'X-Image-Meta-Property-Arch': 'x86_64'} path = "/v1/images/%s" % image_id response, content = self.http.request(path, 'PUT', headers=headers) self.assertEqual(response.status, 200) data = jsonutils.loads(content) path = "/v1/images/detail" response, content = self.http.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content)['images'][0] self.assertEqual(len(data['properties']), 2) self.assertEqual(data['properties']['arch'], "x86_64") self.assertEqual(data['properties']['distro'], "Ubuntu") self.assertNotEqual(data['created_at'], data['updated_at']) # DELETE image path = "/v1/images/%s" % image_id response, content = self.http.request(path, 'DELETE') self.assertEqual(response.status, 200) def test_queued_process_flow(self): """ We test the process flow where a user registers an image with Glance but does not immediately upload an image file. Later, the user uploads an image file using a PUT operation. We track the changing of image status throughout this process. 0. GET /images - Verify no public images 1. POST /images with public image named Image1 with no location attribute and no image data. - Verify 201 returned 2. GET /images - Verify one public image 3. HEAD image - Verify image now in queued status 4. PUT image with image data - Verify 200 returned 5. HEAD images - Verify image now in active status 6. GET /images - Verify one public image """ # 0. GET /images # Verify no public images path = "/v1/images" response, content = self.http.request(path, 'GET') self.assertEqual(response.status, 200) self.assertEqual(content, '{"images": []}') # 1. POST /images with public image named Image1 # with no location or image data headers = minimal_headers('Image1') path = "/v1/images" response, content = self.http.request(path, 'POST', headers=headers) self.assertEqual(response.status, 201) data = jsonutils.loads(content) self.assertIsNone(data['image']['checksum']) self.assertEqual(data['image']['size'], 0) self.assertEqual(data['image']['container_format'], 'ovf') self.assertEqual(data['image']['disk_format'], 'raw') self.assertEqual(data['image']['name'], "Image1") self.assertEqual(data['image']['is_public'], True) image_id = data['image']['id'] # 2. GET /images # Verify 1 public image path = "/v1/images" response, content = self.http.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(data['images'][0]['id'], image_id) self.assertIsNone(data['images'][0]['checksum']) self.assertEqual(data['images'][0]['size'], 0) self.assertEqual(data['images'][0]['container_format'], 'ovf') self.assertEqual(data['images'][0]['disk_format'], 'raw') self.assertEqual(data['images'][0]['name'], "Image1") # 3. HEAD /images # Verify status is in queued path = "/v1/images/%s" % (image_id) response, content = self.http.request(path, 'HEAD') self.assertEqual(response.status, 200) self.assertEqual(response['x-image-meta-name'], "Image1") self.assertEqual(response['x-image-meta-status'], "queued") self.assertEqual(response['x-image-meta-size'], '0') self.assertEqual(response['x-image-meta-id'], image_id) # 4. PUT image with image data, verify 200 returned image_data = "*" * FIVE_KB headers = {'Content-Type': 'application/octet-stream'} path = "/v1/images/%s" % (image_id) response, content = self.http.request(path, 'PUT', headers=headers, body=image_data) self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(data['image']['checksum'], hashlib.md5(image_data).hexdigest()) self.assertEqual(data['image']['size'], FIVE_KB) self.assertEqual(data['image']['name'], "Image1") self.assertEqual(data['image']['is_public'], True) # 5. HEAD /images # Verify status is in active path = "/v1/images/%s" % (image_id) response, content = self.http.request(path, 'HEAD') self.assertEqual(response.status, 200) self.assertEqual(response['x-image-meta-name'], "Image1") self.assertEqual(response['x-image-meta-status'], "active") # 6. GET /images # Verify 1 public image still... path = "/v1/images" response, content = self.http.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(data['images'][0]['checksum'], hashlib.md5(image_data).hexdigest()) self.assertEqual(data['images'][0]['id'], image_id) self.assertEqual(data['images'][0]['size'], FIVE_KB) self.assertEqual(data['images'][0]['container_format'], 'ovf') self.assertEqual(data['images'][0]['disk_format'], 'raw') self.assertEqual(data['images'][0]['name'], "Image1") # DELETE image path = "/v1/images/%s" % (image_id) response, content = self.http.request(path, 'DELETE') self.assertEqual(response.status, 200) def test_size_greater_2G_mysql(self): """ A test against the actual datastore backend for the registry to ensure that the image size property is not truncated. :see https://bugs.launchpad.net/glance/+bug/739433 """ # 1. POST /images with public image named Image1 # attribute and a size of 5G. Use the HTTP engine with an # X-Image-Meta-Location attribute to make Glance forego # "adding" the image data. # Verify a 201 OK is returned headers = {'Content-Type': 'application/octet-stream', 'X-Image-Meta-Location': 'http://example.com/fakeimage', 'X-Image-Meta-Size': str(FIVE_GB), 'X-Image-Meta-Name': 'Image1', 'X-Image-Meta-disk_format': 'raw', 'X-image-Meta-container_format': 'ovf', 'X-Image-Meta-Is-Public': 'True'} path = "/v1/images" response, content = self.http.request(path, 'POST', headers=headers) self.assertEqual(response.status, 201) # 2. HEAD /images # Verify image size is what was passed in, and not truncated path = response.get('location') response, content = self.http.request(path, 'HEAD') self.assertEqual(response.status, 200) self.assertEqual(response['x-image-meta-size'], str(FIVE_GB)) self.assertEqual(response['x-image-meta-name'], 'Image1') self.assertEqual(response['x-image-meta-is_public'], 'True') def test_v1_not_enabled(self): self.config(enable_v1_api=False) path = "/v1/images" response, content = self.http.request(path, 'GET') self.assertEqual(response.status, 300) def test_v1_enabled(self): self.config(enable_v1_api=True) path = "/v1/images" response, content = self.http.request(path, 'GET') self.assertEqual(response.status, 200) def test_zero_initial_size(self): """ A test to ensure that an image with size explicitly set to zero has status that immediately transitions to active. """ # 1. POST /images with public image named Image1 # attribute and a size of zero. # Verify a 201 OK is returned headers = {'Content-Type': 'application/octet-stream', 'X-Image-Meta-Size': '0', 'X-Image-Meta-Name': 'Image1', 'X-Image-Meta-disk_format': 'raw', 'X-image-Meta-container_format': 'ovf', 'X-Image-Meta-Is-Public': 'True'} path = "/v1/images" response, content = self.http.request(path, 'POST', headers=headers) self.assertEqual(response.status, 201) # 2. HEAD image-location # Verify image size is zero and the status is active path = response.get('location') response, content = self.http.request(path, 'HEAD') self.assertEqual(response.status, 200) self.assertEqual(response['x-image-meta-size'], '0') self.assertEqual(response['x-image-meta-status'], 'active') # 3. GET image-location # Verify image content is empty response, content = self.http.request(path, 'GET') self.assertEqual(response.status, 200) self.assertEqual(len(content), 0) def test_traceback_not_consumed(self): """ A test that errors coming from the POST API do not get consumed and print the actual error message, and not something like <traceback object at 0x1918d40> :see https://bugs.launchpad.net/glance/+bug/755912 """ # POST /images with binary data, but not setting # Content-Type to application/octet-stream, verify a # 400 returned and that the error is readable. with tempfile.NamedTemporaryFile() as test_data_file: test_data_file.write("XXX") test_data_file.flush() path = "/v1/images" headers = minimal_headers('Image1') headers['Content-Type'] = 'not octet-stream' response, content = self.http.request(path, 'POST', body=test_data_file.name, headers=headers) self.assertEqual(response.status, 400) expected = "Content-Type must be application/octet-stream" self.assertTrue(expected in content, "Could not find '%s' in '%s'" % (expected, content)) def test_filtered_images(self): """ Set up four test images and ensure each query param filter works """ # 0. GET /images # Verify no public images path = "/v1/images" response, content = self.http.request(path, 'GET') self.assertEqual(response.status, 200) self.assertEqual(content, '{"images": []}') image_ids = [] # 1. POST /images with three public images, and one private image # with various attributes headers = {'Content-Type': 'application/octet-stream', 'X-Image-Meta-Name': 'Image1', 'X-Image-Meta-Status': 'active', 'X-Image-Meta-Container-Format': 'ovf', 'X-Image-Meta-Disk-Format': 'vdi', 'X-Image-Meta-Size': '19', 'X-Image-Meta-Is-Public': 'True', 'X-Image-Meta-Protected': 'True', 'X-Image-Meta-Property-pants': 'are on'} path = "/v1/images" response, content = self.http.request(path, 'POST', headers=headers) self.assertEqual(response.status, 201) data = jsonutils.loads(content) self.assertEqual(data['image']['properties']['pants'], "are on") self.assertEqual(data['image']['is_public'], True) image_ids.append(data['image']['id']) headers = {'Content-Type': 'application/octet-stream', 'X-Image-Meta-Name': 'My Image!', 'X-Image-Meta-Status': 'active', 'X-Image-Meta-Container-Format': 'ovf', 'X-Image-Meta-Disk-Format': 'vhd', 'X-Image-Meta-Size': '20', 'X-Image-Meta-Is-Public': 'True', 'X-Image-Meta-Protected': 'False', 'X-Image-Meta-Property-pants': 'are on'} path = "/v1/images" response, content = self.http.request(path, 'POST', headers=headers) self.assertEqual(response.status, 201) data = jsonutils.loads(content) self.assertEqual(data['image']['properties']['pants'], "are on") self.assertEqual(data['image']['is_public'], True) image_ids.append(data['image']['id']) headers = {'Content-Type': 'application/octet-stream', 'X-Image-Meta-Name': 'My Image!', 'X-Image-Meta-Status': 'saving', 'X-Image-Meta-Container-Format': 'ami', 'X-Image-Meta-Disk-Format': 'ami', 'X-Image-Meta-Size': '21', 'X-Image-Meta-Is-Public': 'True', 'X-Image-Meta-Protected': 'False', 'X-Image-Meta-Property-pants': 'are off'} path = "/v1/images" response, content = self.http.request(path, 'POST', headers=headers) self.assertEqual(response.status, 201) data = jsonutils.loads(content) self.assertEqual(data['image']['properties']['pants'], "are off") self.assertEqual(data['image']['is_public'], True) image_ids.append(data['image']['id']) headers = {'Content-Type': 'application/octet-stream', 'X-Image-Meta-Name': 'My Private Image', 'X-Image-Meta-Status': 'active', 'X-Image-Meta-Container-Format': 'ami', 'X-Image-Meta-Disk-Format': 'ami', 'X-Image-Meta-Size': '22', 'X-Image-Meta-Is-Public': 'False', 'X-Image-Meta-Protected': 'False'} path = "/v1/images" response, content = self.http.request(path, 'POST', headers=headers) self.assertEqual(response.status, 201) data = jsonutils.loads(content) self.assertEqual(data['image']['is_public'], False) image_ids.append(data['image']['id']) # 2. GET /images # Verify three public images path = "/v1/images" response, content = self.http.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(len(data['images']), 3) # 3. GET /images with name filter # Verify correct images returned with name params = "name=My%20Image!" path = "/v1/images?%s" % (params) response, content = self.http.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(len(data['images']), 2) for image in data['images']: self.assertEqual(image['name'], "My Image!") # 4. GET /images with status filter # Verify correct images returned with status params = "status=queued" path = "/v1/images/detail?%s" % (params) response, content = self.http.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(len(data['images']), 3) for image in data['images']: self.assertEqual(image['status'], "queued") params = "status=active" path = "/v1/images/detail?%s" % (params) response, content = self.http.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(len(data['images']), 0) # 5. GET /images with container_format filter # Verify correct images returned with container_format params = "container_format=ovf" path = "/v1/images?%s" % (params) response, content = self.http.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(len(data['images']), 2) for image in data['images']: self.assertEqual(image['container_format'], "ovf") # 6. GET /images with disk_format filter # Verify correct images returned with disk_format params = "disk_format=vdi" path = "/v1/images?%s" % (params) response, content = self.http.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(len(data['images']), 1) for image in data['images']: self.assertEqual(image['disk_format'], "vdi") # 7. GET /images with size_max filter # Verify correct images returned with size <= expected params = "size_max=20" path = "/v1/images?%s" % (params) response, content = self.http.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(len(data['images']), 2) for image in data['images']: self.assertTrue(image['size'] <= 20) # 8. GET /images with size_min filter # Verify correct images returned with size >= expected params = "size_min=20" path = "/v1/images?%s" % (params) response, content = self.http.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(len(data['images']), 2) for image in data['images']: self.assertTrue(image['size'] >= 20) # 9. Get /images with is_public=None filter # Verify correct images returned with property # Bug lp:803656 Support is_public in filtering params = "is_public=None" path = "/v1/images?%s" % (params) response, content = self.http.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(len(data['images']), 4) # 10. Get /images with is_public=False filter # Verify correct images returned with property # Bug lp:803656 Support is_public in filtering params = "is_public=False" path = "/v1/images?%s" % (params) response, content = self.http.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(len(data['images']), 1) for image in data['images']: self.assertEqual(image['name'], "My Private Image") # 11. Get /images with is_public=True filter # Verify correct images returned with property # Bug lp:803656 Support is_public in filtering params = "is_public=True" path = "/v1/images?%s" % (params) response, content = self.http.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(len(data['images']), 3) for image in data['images']: self.assertNotEqual(image['name'], "My Private Image") # 12. Get /images with protected=False filter # Verify correct images returned with property params = "protected=False" path = "/v1/images?%s" % (params) response, content = self.http.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(len(data['images']), 2) for image in data['images']: self.assertNotEqual(image['name'], "Image1") # 13. Get /images with protected=True filter # Verify correct images returned with property params = "protected=True" path = "/v1/images?%s" % (params) response, content = self.http.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(len(data['images']), 1) for image in data['images']: self.assertEqual(image['name'], "Image1") # 14. GET /images with property filter # Verify correct images returned with property params = "property-pants=are%20on" path = "/v1/images/detail?%s" % (params) response, content = self.http.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(len(data['images']), 2) for image in data['images']: self.assertEqual(image['properties']['pants'], "are on") # 15. GET /images with property filter and name filter # Verify correct images returned with property and name # Make sure you quote the url when using more than one param! params = "name=My%20Image!&property-pants=are%20on" path = "/v1/images/detail?%s" % (params) response, content = self.http.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(len(data['images']), 1) for image in data['images']: self.assertEqual(image['properties']['pants'], "are on") self.assertEqual(image['name'], "My Image!") # 16. GET /images with past changes-since filter yesterday = timeutils.isotime(timeutils.utcnow() - datetime.timedelta(1)) params = "changes-since=%s" % yesterday path = "/v1/images?%s" % (params) response, content = self.http.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(len(data['images']), 3) # one timezone west of Greenwich equates to an hour ago # taking care to pre-urlencode '+' as '%2B', otherwise the timezone # '+' is wrongly decoded as a space # TODO(eglynn): investigate '+' --> decoding, an artifact # of WSGI/webob dispatch? now = timeutils.utcnow() hour_ago = now.strftime('%Y-%m-%dT%H:%M:%S%%2B01:00') params = "changes-since=%s" % hour_ago path = "/v1/images?%s" % (params) response, content = self.http.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(len(data['images']), 3) # 17. GET /images with future changes-since filter tomorrow = timeutils.isotime(timeutils.utcnow() + datetime.timedelta(1)) params = "changes-since=%s" % tomorrow path = "/v1/images?%s" % (params) response, content = self.http.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(len(data['images']), 0) # one timezone east of Greenwich equates to an hour from now now = timeutils.utcnow() hour_hence = now.strftime('%Y-%m-%dT%H:%M:%S-01:00') params = "changes-since=%s" % hour_hence path = "/v1/images?%s" % (params) response, content = self.http.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(len(data['images']), 0) # 18. GET /images with size_min filter # Verify correct images returned with size >= expected params = "size_min=-1" path = "/v1/images?%s" % (params) response, content = self.http.request(path, 'GET') self.assertEqual(response.status, 400) self.assertTrue("filter size_min got -1" in content) # 19. GET /images with size_min filter # Verify correct images returned with size >= expected params = "size_max=-1" path = "/v1/images?%s" % (params) response, content = self.http.request(path, 'GET') self.assertEqual(response.status, 400) self.assertTrue("filter size_max got -1" in content) # 20. GET /images with size_min filter # Verify correct images returned with size >= expected params = "min_ram=-1" path = "/v1/images?%s" % (params) response, content = self.http.request(path, 'GET') self.assertEqual(response.status, 400) self.assertTrue("Bad value passed to filter min_ram got -1" in content) # 21. GET /images with size_min filter # Verify correct images returned with size >= expected params = "protected=imalittleteapot" path = "/v1/images?%s" % (params) response, content = self.http.request(path, 'GET') self.assertEqual(response.status, 400) self.assertTrue("protected got imalittleteapot" in content) # 22. GET /images with size_min filter # Verify correct images returned with size >= expected params = "is_public=imalittleteapot" path = "/v1/images?%s" % (params) response, content = self.http.request(path, 'GET') self.assertEqual(response.status, 400) self.assertTrue("is_public got imalittleteapot" in content) def test_limited_images(self): """ Ensure marker and limit query params work """ # 0. GET /images # Verify no public images path = "/v1/images" response, content = self.http.request(path, 'GET') self.assertEqual(response.status, 200) self.assertEqual(content, '{"images": []}') image_ids = [] # 1. POST /images with three public images with various attributes headers = minimal_headers('Image1') path = "/v1/images" response, content = self.http.request(path, 'POST', headers=headers) self.assertEqual(response.status, 201) image_ids.append(jsonutils.loads(content)['image']['id']) headers = minimal_headers('Image2') path = "/v1/images" response, content = self.http.request(path, 'POST', headers=headers) self.assertEqual(response.status, 201) image_ids.append(jsonutils.loads(content)['image']['id']) headers = minimal_headers('Image3') path = "/v1/images" response, content = self.http.request(path, 'POST', headers=headers) self.assertEqual(response.status, 201) image_ids.append(jsonutils.loads(content)['image']['id']) # 2. GET /images with all images path = "/v1/images" response, content = self.http.request(path, 'GET') self.assertEqual(response.status, 200) images = jsonutils.loads(content)['images'] self.assertEqual(len(images), 3) # 3. GET /images with limit of 2 # Verify only two images were returned params = "limit=2" path = "/v1/images?%s" % (params) response, content = self.http.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content)['images'] self.assertEqual(len(data), 2) self.assertEqual(data[0]['id'], images[0]['id']) self.assertEqual(data[1]['id'], images[1]['id']) # 4. GET /images with marker # Verify only two images were returned params = "marker=%s" % images[0]['id'] path = "/v1/images?%s" % (params) response, content = self.http.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content)['images'] self.assertEqual(len(data), 2) self.assertEqual(data[0]['id'], images[1]['id']) self.assertEqual(data[1]['id'], images[2]['id']) # 5. GET /images with marker and limit # Verify only one image was returned with the correct id params = "limit=1&marker=%s" % images[1]['id'] path = "/v1/images?%s" % (params) response, content = self.http.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content)['images'] self.assertEqual(len(data), 1) self.assertEqual(data[0]['id'], images[2]['id']) # 6. GET /images/detail with marker and limit # Verify only one image was returned with the correct id params = "limit=1&marker=%s" % images[1]['id'] path = "/v1/images?%s" % (params) response, content = self.http.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content)['images'] self.assertEqual(len(data), 1) self.assertEqual(data[0]['id'], images[2]['id']) # DELETE images for image_id in image_ids: path = "/v1/images/%s" % (image_id) response, content = self.http.request(path, 'DELETE') self.assertEqual(response.status, 200) def test_ordered_images(self): """ Set up three test images and ensure each query param filter works """ # 0. GET /images # Verify no public images path = "/v1/images" response, content = self.http.request(path, 'GET') self.assertEqual(response.status, 200) self.assertEqual(content, '{"images": []}') # 1. POST /images with three public images with various attributes image_ids = [] headers = {'Content-Type': 'application/octet-stream', 'X-Image-Meta-Name': 'Image1', 'X-Image-Meta-Status': 'active', 'X-Image-Meta-Container-Format': 'ovf', 'X-Image-Meta-Disk-Format': 'vdi', 'X-Image-Meta-Size': '19', 'X-Image-Meta-Is-Public': 'True'} path = "/v1/images" response, content = self.http.request(path, 'POST', headers=headers) self.assertEqual(response.status, 201) image_ids.append(jsonutils.loads(content)['image']['id']) headers = {'Content-Type': 'application/octet-stream', 'X-Image-Meta-Name': 'ASDF', 'X-Image-Meta-Status': 'active', 'X-Image-Meta-Container-Format': 'bare', 'X-Image-Meta-Disk-Format': 'iso', 'X-Image-Meta-Size': '2', 'X-Image-Meta-Is-Public': 'True'} path = "/v1/images" response, content = self.http.request(path, 'POST', headers=headers) self.assertEqual(response.status, 201) image_ids.append(jsonutils.loads(content)['image']['id']) headers = {'Content-Type': 'application/octet-stream', 'X-Image-Meta-Name': 'XYZ', 'X-Image-Meta-Status': 'saving', 'X-Image-Meta-Container-Format': 'ami', 'X-Image-Meta-Disk-Format': 'ami', 'X-Image-Meta-Size': '5', 'X-Image-Meta-Is-Public': 'True'} path = "/v1/images" response, content = self.http.request(path, 'POST', headers=headers) self.assertEqual(response.status, 201) image_ids.append(jsonutils.loads(content)['image']['id']) # 2. GET /images with no query params # Verify three public images sorted by created_at desc path = "/v1/images" response, content = self.http.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(len(data['images']), 3) self.assertEqual(data['images'][0]['id'], image_ids[2]) self.assertEqual(data['images'][1]['id'], image_ids[1]) self.assertEqual(data['images'][2]['id'], image_ids[0]) # 3. GET /images sorted by name asc params = 'sort_key=name&sort_dir=asc' path = "/v1/images?%s" % (params) response, content = self.http.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(len(data['images']), 3) self.assertEqual(data['images'][0]['id'], image_ids[1]) self.assertEqual(data['images'][1]['id'], image_ids[0]) self.assertEqual(data['images'][2]['id'], image_ids[2]) # 4. GET /images sorted by size desc params = 'sort_key=size&sort_dir=desc' path = "/v1/images?%s" % (params) response, content = self.http.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(len(data['images']), 3) self.assertEqual(data['images'][0]['id'], image_ids[0]) self.assertEqual(data['images'][1]['id'], image_ids[2]) self.assertEqual(data['images'][2]['id'], image_ids[1]) # 5. GET /images sorted by size desc with a marker params = 'sort_key=size&sort_dir=desc&marker=%s' % image_ids[0] path = "/v1/images?%s" % (params) response, content = self.http.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(len(data['images']), 2) self.assertEqual(data['images'][0]['id'], image_ids[2]) self.assertEqual(data['images'][1]['id'], image_ids[1]) # 6. GET /images sorted by name asc with a marker params = 'sort_key=name&sort_dir=asc&marker=%s' % image_ids[2] path = "/v1/images?%s" % (params) response, content = self.http.request(path, 'GET') self.assertEqual(response.status, 200) data = jsonutils.loads(content) self.assertEqual(len(data['images']), 0) # DELETE images for image_id in image_ids: path = "/v1/images/%s" % (image_id) response, content = self.http.request(path, 'DELETE') self.assertEqual(response.status, 200) def test_duplicate_image_upload(self): """ Upload initial image, then attempt to upload duplicate image """ # 0. GET /images # Verify no public images path = "/v1/images" response, content = self.http.request(path, 'GET') self.assertEqual(response.status, 200) self.assertEqual(content, '{"images": []}') # 1. POST /images with public image named Image1 headers = {'Content-Type': 'application/octet-stream', 'X-Image-Meta-Name': 'Image1', 'X-Image-Meta-Status': 'active', 'X-Image-Meta-Container-Format': 'ovf', 'X-Image-Meta-Disk-Format': 'vdi', 'X-Image-Meta-Size': '19', 'X-Image-Meta-Is-Public': 'True'} path = "/v1/images" response, content = self.http.request(path, 'POST', headers=headers) self.assertEqual(response.status, 201) image = jsonutils.loads(content)['image'] # 2. POST /images with public image named Image1, and ID: 1 headers = {'Content-Type': 'application/octet-stream', 'X-Image-Meta-Name': 'Image1 Update', 'X-Image-Meta-Status': 'active', 'X-Image-Meta-Container-Format': 'ovf', 'X-Image-Meta-Disk-Format': 'vdi', 'X-Image-Meta-Size': '19', 'X-Image-Meta-Id': image['id'], 'X-Image-Meta-Is-Public': 'True'} path = "/v1/images" response, content = self.http.request(path, 'POST', headers=headers) self.assertEqual(response.status, 409) def test_delete_not_existing(self): """ We test the following: 0. GET /images/1 - Verify 404 1. DELETE /images/1 - Verify 404 """ # 0. GET /images # Verify no public images path = "/v1/images" response, content = self.http.request(path, 'GET') self.assertEqual(response.status, 200) self.assertEqual(content, '{"images": []}') # 1. DELETE /images/1 # Verify 404 returned path = "/v1/images/1" response, content = self.http.request(path, 'DELETE') self.assertEqual(response.status, 404) def _do_test_post_image_content_bad_format(self, format): """ We test that missing container/disk format fails with 400 "Bad Request" :see https://bugs.launchpad.net/glance/+bug/933702 """ # Verify no public images path = "/v1/images" response, content = self.http.request(path, 'GET') self.assertEqual(response.status, 200) images = jsonutils.loads(content)['images'] self.assertEqual(len(images), 0) path = "/v1/images" # POST /images without given format being specified headers = minimal_headers('Image1') headers['X-Image-Meta-' + format] = 'bad_value' with tempfile.NamedTemporaryFile() as test_data_file: test_data_file.write("XXX") test_data_file.flush() response, content = self.http.request(path, 'POST', headers=headers, body=test_data_file.name) self.assertEqual(response.status, 400) type = format.replace('_format', '') expected = "Invalid %s format 'bad_value' for image" % type self.assertTrue(expected in content, "Could not find '%s' in '%s'" % (expected, content)) # make sure the image was not created # Verify no public images path = "/v1/images" response, content = self.http.request(path, 'GET') self.assertEqual(response.status, 200) images = jsonutils.loads(content)['images'] self.assertEqual(len(images), 0) def test_post_image_content_bad_container_format(self): self._do_test_post_image_content_bad_format('container_format') def test_post_image_content_bad_disk_format(self): self._do_test_post_image_content_bad_format('disk_format') def _do_test_put_image_content_missing_format(self, format): """ We test that missing container/disk format only fails with 400 "Bad Request" when the image content is PUT (i.e. not on the original POST of a queued image). :see https://bugs.launchpad.net/glance/+bug/937216 """ # POST queued image path = "/v1/images" headers = { 'X-Image-Meta-Name': 'Image1', 'X-Image-Meta-Is-Public': 'True', } response, content = self.http.request(path, 'POST', headers=headers) self.assertEqual(response.status, 201) data = jsonutils.loads(content) image_id = data['image']['id'] self.addDetail('image_data', testtools.content.json_content(data)) # PUT image content images without given format being specified path = "/v1/images/%s" % (image_id) headers = minimal_headers('Image1') del headers['X-Image-Meta-' + format] with tempfile.NamedTemporaryFile() as test_data_file: test_data_file.write("XXX") test_data_file.flush() response, content = self.http.request(path, 'PUT', headers=headers, body=test_data_file.name) self.assertEqual(response.status, 400) type = format.replace('_format', '') expected = "Invalid %s format 'None' for image" % type self.assertTrue(expected in content, "Could not find '%s' in '%s'" % (expected, content)) def test_put_image_content_bad_container_format(self): self._do_test_put_image_content_missing_format('container_format') def test_put_image_content_bad_disk_format(self): self._do_test_put_image_content_missing_format('disk_format') def _do_test_mismatched_attribute(self, attribute, value): """ Test mismatched attribute. """ image_data = "*" * FIVE_KB headers = minimal_headers('Image1') headers[attribute] = value path = "/v1/images" response, content = self.http.request(path, 'POST', headers=headers, body=image_data) self.assertEqual(response.status, 400) images_dir = os.path.join(self.test_dir, 'images') image_count = len([name for name in os.listdir(images_dir) if os.path.isfile(os.path.join(images_dir, name))]) self.assertEqual(image_count, 0) def test_mismatched_size(self): """ Test mismatched size. """ self._do_test_mismatched_attribute('x-image-meta-size', str(FIVE_KB + 1)) def test_mismatched_checksum(self): """ Test mismatched checksum. """ self._do_test_mismatched_attribute('x-image-meta-checksum', 'foobar') class TestApiWithFakeAuth(base.ApiTest): def __init__(self, *args, **kwargs): super(TestApiWithFakeAuth, self).__init__(*args, **kwargs) self.api_flavor = 'fakeauth' self.registry_flavor = 'fakeauth' def test_ownership(self): # Add an image with admin privileges and ensure the owner # can be set to something other than what was used to authenticate auth_headers = { 'X-Auth-Token': 'user1:tenant1:admin', } create_headers = { 'X-Image-Meta-Name': 'MyImage', 'X-Image-Meta-disk_format': 'raw', 'X-Image-Meta-container_format': 'ovf', 'X-Image-Meta-Is-Public': 'True', 'X-Image-Meta-Owner': 'tenant2', } create_headers.update(auth_headers) path = "/v1/images" response, content = self.http.request(path, 'POST', headers=create_headers) self.assertEqual(response.status, 201) data = jsonutils.loads(content) image_id = data['image']['id'] path = "/v1/images/%s" % (image_id) response, content = self.http.request(path, 'HEAD', headers=auth_headers) self.assertEqual(response.status, 200) self.assertEqual('tenant2', response['x-image-meta-owner']) # Now add an image without admin privileges and ensure the owner # cannot be set to something other than what was used to authenticate auth_headers = { 'X-Auth-Token': 'user1:tenant1:role1', } create_headers.update(auth_headers) path = "/v1/images" response, content = self.http.request(path, 'POST', headers=create_headers) self.assertEqual(response.status, 201) data = jsonutils.loads(content) image_id = data['image']['id'] # We have to be admin to see the owner auth_headers = { 'X-Auth-Token': 'user1:tenant1:admin', } create_headers.update(auth_headers) path = "/v1/images/%s" % (image_id) response, content = self.http.request(path, 'HEAD', headers=auth_headers) self.assertEqual(response.status, 200) self.assertEqual('tenant1', response['x-image-meta-owner']) # Make sure the non-privileged user can't update their owner either update_headers = { 'X-Image-Meta-Name': 'MyImage2', 'X-Image-Meta-Owner': 'tenant2', 'X-Auth-Token': 'user1:tenant1:role1', } path = "/v1/images/%s" % (image_id) response, content = self.http.request(path, 'PUT', headers=update_headers) self.assertEqual(response.status, 200) # We have to be admin to see the owner auth_headers = { 'X-Auth-Token': 'user1:tenant1:admin', } path = "/v1/images/%s" % (image_id) response, content = self.http.request(path, 'HEAD', headers=auth_headers) self.assertEqual(response.status, 200) self.assertEqual('tenant1', response['x-image-meta-owner']) # An admin user should be able to update the owner auth_headers = { 'X-Auth-Token': 'user1:tenant3:admin', } update_headers = { 'X-Image-Meta-Name': 'MyImage2', 'X-Image-Meta-Owner': 'tenant2', } update_headers.update(auth_headers) path = "/v1/images/%s" % (image_id) response, content = self.http.request(path, 'PUT', headers=update_headers) self.assertEqual(response.status, 200) path = "/v1/images/%s" % (image_id) response, content = self.http.request(path, 'HEAD', headers=auth_headers) self.assertEqual(response.status, 200) self.assertEqual('tenant2', response['x-image-meta-owner']) def test_image_visibility_to_different_users(self): owners = ['admin', 'tenant1', 'tenant2', 'none'] visibilities = {'public': 'True', 'private': 'False'} image_ids = {} for owner in owners: for visibility, is_public in visibilities.items(): name = '%s-%s' % (owner, visibility) headers = { 'Content-Type': 'application/octet-stream', 'X-Image-Meta-Name': name, 'X-Image-Meta-Status': 'active', 'X-Image-Meta-Is-Public': is_public, 'X-Image-Meta-Owner': owner, 'X-Auth-Token': 'createuser:createtenant:admin', } path = "/v1/images" response, content = self.http.request(path, 'POST', headers=headers) self.assertEqual(response.status, 201) data = jsonutils.loads(content) image_ids[name] = data['image']['id'] def list_images(tenant, role='', is_public=None): auth_token = 'user:%s:%s' % (tenant, role) headers = {'X-Auth-Token': auth_token} path = "/v1/images/detail" if is_public is not None: path += '?is_public=%s' % is_public response, content = self.http.request(path, 'GET', headers=headers) self.assertEqual(response.status, 200) return jsonutils.loads(content)['images'] # 1. Known user sees public and their own images images = list_images('tenant1') self.assertEqual(len(images), 5) for image in images: self.assertTrue(image['is_public'] or image['owner'] == 'tenant1') # 2. Unknown user sees only public images images = list_images('none') self.assertEqual(len(images), 4) for image in images: self.assertTrue(image['is_public']) # 3. Unknown admin sees only public images images = list_images('none', role='admin') self.assertEqual(len(images), 4) for image in images: self.assertTrue(image['is_public']) # 4. Unknown admin, is_public=none, shows all images images = list_images('none', role='admin', is_public='none') self.assertEqual(len(images), 8) # 5. Unknown admin, is_public=true, shows only public images images = list_images('none', role='admin', is_public='true') self.assertEqual(len(images), 4) for image in images: self.assertTrue(image['is_public']) # 6. Unknown admin, is_public=false, sees only private images images = list_images('none', role='admin', is_public='false') self.assertEqual(len(images), 4) for image in images: self.assertFalse(image['is_public']) # 7. Known admin sees public and their own images images = list_images('admin', role='admin') self.assertEqual(len(images), 5) for image in images: self.assertTrue(image['is_public'] or image['owner'] == 'admin') # 8. Known admin, is_public=none, shows all images images = list_images('admin', role='admin', is_public='none') self.assertEqual(len(images), 8) # 9. Known admin, is_public=true, sees all public and their images images = list_images('admin', role='admin', is_public='true') self.assertEqual(len(images), 5) for image in images: self.assertTrue(image['is_public'] or image['owner'] == 'admin') # 10. Known admin, is_public=false, sees all private images images = list_images('admin', role='admin', is_public='false') self.assertEqual(len(images), 4) for image in images: self.assertFalse(image['is_public']) def test_property_protections(self): # Enable property protection self.config(property_protection_file=self.property_file) self.setUp() CREATE_HEADERS = { 'X-Image-Meta-Name': 'MyImage', 'X-Image-Meta-disk_format': 'raw', 'X-Image-Meta-container_format': 'ovf', 'X-Image-Meta-Is-Public': 'True', 'X-Image-Meta-Owner': 'tenant2', } # Create an image for role member with extra properties # Raises 403 since user is not allowed to create 'foo' auth_headers = { 'X-Auth-Token': 'user1:tenant1:member', } custom_props = { 'x-image-meta-property-foo': 'bar' } auth_headers.update(custom_props) auth_headers.update(CREATE_HEADERS) path = "/v1/images" response, content = self.http.request(path, 'POST', headers=auth_headers) self.assertEqual(response.status, 403) # Create an image for role member without 'foo' auth_headers = { 'X-Auth-Token': 'user1:tenant1:member', } custom_props = { 'x-image-meta-property-x_owner_foo': 'o_s_bar', } auth_headers.update(custom_props) auth_headers.update(CREATE_HEADERS) path = "/v1/images" response, content = self.http.request(path, 'POST', headers=auth_headers) self.assertEqual(response.status, 201) # Returned image entity should have 'x_owner_foo' data = jsonutils.loads(content) self.assertEqual(data['image']['properties']['x_owner_foo'], 'o_s_bar') # Create an image for role spl_role with extra properties auth_headers = { 'X-Auth-Token': 'user1:tenant1:spl_role', } custom_props = { 'X-Image-Meta-Property-spl_create_prop': 'create_bar', 'X-Image-Meta-Property-spl_read_prop': 'read_bar', 'X-Image-Meta-Property-spl_update_prop': 'update_bar', 'X-Image-Meta-Property-spl_delete_prop': 'delete_bar' } auth_headers.update(custom_props) auth_headers.update(CREATE_HEADERS) path = "/v1/images" response, content = self.http.request(path, 'POST', headers=auth_headers) self.assertEqual(response.status, 201) data = jsonutils.loads(content) image_id = data['image']['id'] # Attempt to update two properties, one protected(spl_read_prop), the # other not(spl_update_prop). Request should be forbidden. auth_headers = { 'X-Auth-Token': 'user1:tenant1:spl_role', } custom_props = { 'X-Image-Meta-Property-spl_read_prop': 'r', 'X-Image-Meta-Property-spl_update_prop': 'u', 'X-Glance-Registry-Purge-Props': 'False' } auth_headers.update(auth_headers) auth_headers.update(custom_props) path = "/v1/images/%s" % image_id response, content = self.http.request(path, 'PUT', headers=auth_headers) self.assertEqual(response.status, 403) # Attempt to create properties which are forbidden auth_headers = { 'X-Auth-Token': 'user1:tenant1:spl_role', } custom_props = { 'X-Image-Meta-Property-spl_new_prop': 'new', 'X-Glance-Registry-Purge-Props': 'True' } auth_headers.update(auth_headers) auth_headers.update(custom_props) path = "/v1/images/%s" % image_id response, content = self.http.request(path, 'PUT', headers=auth_headers) self.assertEqual(response.status, 403) # Attempt to update, create and delete properties auth_headers = { 'X-Auth-Token': 'user1:tenant1:spl_role', } custom_props = { 'X-Image-Meta-Property-spl_create_prop': 'create_bar', 'X-Image-Meta-Property-spl_read_prop': 'read_bar', 'X-Image-Meta-Property-spl_update_prop': 'u', 'X-Glance-Registry-Purge-Props': 'True' } auth_headers.update(auth_headers) auth_headers.update(custom_props) path = "/v1/images/%s" % image_id response, content = self.http.request(path, 'PUT', headers=auth_headers) self.assertEqual(response.status, 200) # Returned image entity should reflect the changes image = jsonutils.loads(content) # 'spl_update_prop' has update permission for spl_role # hence the value has changed self.assertEqual('u', image['image']['properties']['spl_update_prop']) # 'spl_delete_prop' has delete permission for spl_role # hence the property has been deleted self.assertTrue('spl_delete_prop' not in image['image']['properties']) # 'spl_create_prop' has create permission for spl_role # hence the property has been created self.assertEqual('create_bar', image['image']['properties']['spl_create_prop']) # Image Deletion should work auth_headers = { 'X-Auth-Token': 'user1:tenant1:spl_role', } path = "/v1/images/%s" % image_id response, content = self.http.request(path, 'DELETE', headers=auth_headers) self.assertEqual(response.status, 200) # This image should be no longer be directly accessible auth_headers = { 'X-Auth-Token': 'user1:tenant1:spl_role', } path = "/v1/images/%s" % image_id response, content = self.http.request(path, 'HEAD', headers=auth_headers) self.assertEqual(response.status, 404) def test_property_protections_special_chars(self): # Enable property protection self.config(property_protection_file=self.property_file) self.setUp() CREATE_HEADERS = { 'X-Image-Meta-Name': 'MyImage', 'X-Image-Meta-disk_format': 'raw', 'X-Image-Meta-container_format': 'ovf', 'X-Image-Meta-Is-Public': 'True', 'X-Image-Meta-Owner': 'tenant2', 'X-Image-Meta-Size': '0', } # Create an image auth_headers = { 'X-Auth-Token': 'user1:tenant1:member', } auth_headers.update(CREATE_HEADERS) path = "/v1/images" response, content = self.http.request(path, 'POST', headers=auth_headers) self.assertEqual(response.status, 201) data = jsonutils.loads(content) image_id = data['image']['id'] # Verify both admin and unknown role can create properties marked with # '@' auth_headers = { 'X-Auth-Token': 'user1:tenant1:admin', } custom_props = { 'X-Image-Meta-Property-x_all_permitted_admin': '1' } auth_headers.update(custom_props) path = "/v1/images/%s" % image_id response, content = self.http.request(path, 'PUT', headers=auth_headers) self.assertEqual(response.status, 200) image = jsonutils.loads(content) self.assertEqual('1', image['image']['properties']['x_all_permitted_admin']) auth_headers = { 'X-Auth-Token': 'user1:tenant1:joe_soap', } custom_props = { 'X-Image-Meta-Property-x_all_permitted_joe_soap': '1', 'X-Glance-Registry-Purge-Props': 'False' } auth_headers.update(custom_props) path = "/v1/images/%s" % image_id response, content = self.http.request(path, 'PUT', headers=auth_headers) self.assertEqual(response.status, 200) image = jsonutils.loads(content) self.assertEqual( '1', image['image']['properties']['x_all_permitted_joe_soap']) # Verify both admin and unknown role can read properties marked with # '@' auth_headers = { 'X-Auth-Token': 'user1:tenant1:admin', } path = "/v1/images/%s" % image_id response, content = self.http.request(path, 'HEAD', headers=auth_headers) self.assertEqual(response.status, 200) self.assertEqual('1', response.get( 'x-image-meta-property-x_all_permitted_admin')) self.assertEqual('1', response.get( 'x-image-meta-property-x_all_permitted_joe_soap')) auth_headers = { 'X-Auth-Token': 'user1:tenant1:joe_soap', } path = "/v1/images/%s" % image_id response, content = self.http.request(path, 'HEAD', headers=auth_headers) self.assertEqual(response.status, 200) self.assertEqual('1', response.get( 'x-image-meta-property-x_all_permitted_admin')) self.assertEqual('1', response.get( 'x-image-meta-property-x_all_permitted_joe_soap')) # Verify both admin and unknown role can update properties marked with # '@' auth_headers = { 'X-Auth-Token': 'user1:tenant1:admin', } custom_props = { 'X-Image-Meta-Property-x_all_permitted_admin': '2', 'X-Glance-Registry-Purge-Props': 'False' } auth_headers.update(custom_props) path = "/v1/images/%s" % image_id response, content = self.http.request(path, 'PUT', headers=auth_headers) self.assertEqual(response.status, 200) image = jsonutils.loads(content) self.assertEqual('2', image['image']['properties']['x_all_permitted_admin']) auth_headers = { 'X-Auth-Token': 'user1:tenant1:joe_soap', } custom_props = { 'X-Image-Meta-Property-x_all_permitted_joe_soap': '2', 'X-Glance-Registry-Purge-Props': 'False' } auth_headers.update(custom_props) path = "/v1/images/%s" % image_id response, content = self.http.request(path, 'PUT', headers=auth_headers) self.assertEqual(response.status, 200) image = jsonutils.loads(content) self.assertEqual( '2', image['image']['properties']['x_all_permitted_joe_soap']) # Verify both admin and unknown role can delete properties marked with # '@' auth_headers = { 'X-Auth-Token': 'user1:tenant1:admin', } custom_props = { 'X-Image-Meta-Property-x_all_permitted_joe_soap': '2', 'X-Glance-Registry-Purge-Props': 'True' } auth_headers.update(custom_props) path = "/v1/images/%s" % image_id response, content = self.http.request(path, 'PUT', headers=auth_headers) self.assertEqual(response.status, 200) image = jsonutils.loads(content) self.assertNotIn('x_all_permitted_admin', image['image']['properties']) auth_headers = { 'X-Auth-Token': 'user1:tenant1:joe_soap', } custom_props = { 'X-Glance-Registry-Purge-Props': 'True' } auth_headers.update(custom_props) path = "/v1/images/%s" % image_id response, content = self.http.request(path, 'PUT', headers=auth_headers) self.assertEqual(response.status, 200) image = jsonutils.loads(content) self.assertNotIn('x_all_permitted_joe_soap', image['image']['properties']) # Verify neither admin nor unknown role can create a property protected # with '!' auth_headers = { 'X-Auth-Token': 'user1:tenant1:admin', } custom_props = { 'X-Image-Meta-Property-x_none_permitted_admin': '1' } auth_headers.update(custom_props) path = "/v1/images/%s" % image_id response, content = self.http.request(path, 'PUT', headers=auth_headers) self.assertEqual(response.status, 403) auth_headers = { 'X-Auth-Token': 'user1:tenant1:joe_soap', } custom_props = { 'X-Image-Meta-Property-x_none_permitted_joe_soap': '1' } auth_headers.update(custom_props) path = "/v1/images/%s" % image_id response, content = self.http.request(path, 'PUT', headers=auth_headers) self.assertEqual(response.status, 403) # Verify neither admin nor unknown role can read properties marked with # '!' auth_headers = { 'X-Auth-Token': 'user1:tenant1:admin', } custom_props = { 'X-Image-Meta-Property-x_none_read': '1' } auth_headers.update(custom_props) auth_headers.update(CREATE_HEADERS) path = "/v1/images" response, content = self.http.request(path, 'POST', headers=auth_headers) self.assertEqual(response.status, 201) data = jsonutils.loads(content) image_id = data['image']['id'] auth_headers = { 'X-Auth-Token': 'user1:tenant1:admin', } path = "/v1/images/%s" % image_id response, content = self.http.request(path, 'HEAD', headers=auth_headers) self.assertEqual(response.status, 200) self.assertRaises(KeyError, response.get, 'X-Image-Meta-Property-x_none_read') auth_headers = { 'X-Auth-Token': 'user1:tenant1:joe_soap', } path = "/v1/images/%s" % image_id response, content = self.http.request(path, 'HEAD', headers=auth_headers) self.assertEqual(response.status, 200) self.assertRaises(KeyError, response.get, 'X-Image-Meta-Property-x_none_read') # Verify neither admin nor unknown role can update properties marked # with '!' auth_headers = { 'X-Auth-Token': 'user1:tenant1:admin', } custom_props = { 'X-Image-Meta-Property-x_none_update': '1' } auth_headers.update(custom_props) auth_headers.update(CREATE_HEADERS) path = "/v1/images" response, content = self.http.request(path, 'POST', headers=auth_headers) self.assertEqual(response.status, 201) data = jsonutils.loads(content) image_id = data['image']['id'] auth_headers = { 'X-Auth-Token': 'user1:tenant1:admin', } custom_props = { 'X-Image-Meta-Property-x_none_update': '2' } auth_headers.update(custom_props) path = "/v1/images/%s" % image_id response, content = self.http.request(path, 'PUT', headers=auth_headers) self.assertEqual(response.status, 403) auth_headers = { 'X-Auth-Token': 'user1:tenant1:joe_soap', } custom_props = { 'X-Image-Meta-Property-x_none_update': '2' } auth_headers.update(custom_props) path = "/v1/images/%s" % image_id response, content = self.http.request(path, 'PUT', headers=auth_headers) self.assertEqual(response.status, 403) # Verify neither admin nor unknown role can delete properties marked # with '!' auth_headers = { 'X-Auth-Token': 'user1:tenant1:admin', } custom_props = { 'X-Image-Meta-Property-x_none_delete': '1' } auth_headers.update(custom_props) auth_headers.update(CREATE_HEADERS) path = "/v1/images" response, content = self.http.request(path, 'POST', headers=auth_headers) self.assertEqual(response.status, 201) data = jsonutils.loads(content) image_id = data['image']['id'] auth_headers = { 'X-Auth-Token': 'user1:tenant1:admin', } custom_props = { 'X-Glance-Registry-Purge-Props': 'True' } auth_headers.update(custom_props) path = "/v1/images/%s" % image_id response, content = self.http.request(path, 'PUT', headers=auth_headers) self.assertEqual(response.status, 403) auth_headers = { 'X-Auth-Token': 'user1:tenant1:joe_soap', } custom_props = { 'X-Glance-Registry-Purge-Props': 'True' } auth_headers.update(custom_props) path = "/v1/images/%s" % image_id response, content = self.http.request(path, 'PUT', headers=auth_headers) self.assertEqual(response.status, 403) glance-2014.1/glance/tests/integration/legacy_functional/base.py0000664000175400017540000001575212323736226026100 0ustar jenkinsjenkins00000000000000# 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 atexit import os.path import tempfile import fixtures from oslo.config import cfg import glance.common.client from glance.common import config from glance.db import migration import glance.db.sqlalchemy.api import glance.registry.client.v1.client import glance.store from glance import tests as glance_tests from glance.tests import utils as test_utils TESTING_API_PASTE_CONF = """ [pipeline:glance-api] pipeline = versionnegotiation gzip unauthenticated-context rootapp [pipeline:glance-api-caching] pipeline = versionnegotiation gzip unauthenticated-context cache rootapp [pipeline:glance-api-cachemanagement] pipeline = versionnegotiation gzip unauthenticated-context cache cache_manage rootapp [pipeline:glance-api-fakeauth] pipeline = versionnegotiation gzip fakeauth context rootapp [pipeline:glance-api-noauth] pipeline = versionnegotiation gzip context rootapp [composite:rootapp] paste.composite_factory = glance.api:root_app_factory /: apiversions /v1: apiv1app /v2: apiv2app [app:apiversions] paste.app_factory = glance.api.versions:create_resource [app:apiv1app] paste.app_factory = glance.api.v1.router:API.factory [app:apiv2app] paste.app_factory = glance.api.v2.router:API.factory [filter:versionnegotiation] paste.filter_factory = glance.api.middleware.version_negotiation:VersionNegotiationFilter.factory [filter:gzip] paste.filter_factory = glance.api.middleware.gzip:GzipMiddleware.factory [filter:cache] paste.filter_factory = glance.api.middleware.cache:CacheFilter.factory [filter:cache_manage] paste.filter_factory = glance.api.middleware.cache_manage:CacheManageFilter.factory [filter:context] paste.filter_factory = glance.api.middleware.context:ContextMiddleware.factory [filter:unauthenticated-context] paste.filter_factory = glance.api.middleware.context:UnauthenticatedContextMiddleware.factory [filter:fakeauth] paste.filter_factory = glance.tests.utils:FakeAuthMiddleware.factory """ TESTING_REGISTRY_PASTE_CONF = """ [pipeline:glance-registry] pipeline = unauthenticated-context registryapp [pipeline:glance-registry-fakeauth] pipeline = fakeauth context registryapp [app:registryapp] paste.app_factory = glance.registry.api.v1:API.factory [filter:context] paste.filter_factory = glance.api.middleware.context:ContextMiddleware.factory [filter:unauthenticated-context] paste.filter_factory = glance.api.middleware.context:UnauthenticatedContextMiddleware.factory [filter:fakeauth] paste.filter_factory = glance.tests.utils:FakeAuthMiddleware.factory """ CONF = cfg.CONF CONF.import_opt('filesystem_store_datadir', 'glance.store.filesystem') CONF.import_opt('backend', 'glance.openstack.common.db.api', group='database') class ApiTest(test_utils.BaseTestCase): def setUp(self): super(ApiTest, self).setUp() self.test_dir = self.useFixture(fixtures.TempDir()).path self._configure_logging() self._setup_database() self._setup_stores() self._setup_property_protection() self.glance_registry_app = self._load_paste_app( 'glance-registry', flavor=getattr(self, 'registry_flavor', ''), conf=getattr(self, 'registry_paste_conf', TESTING_REGISTRY_PASTE_CONF), ) self._connect_registry_client() self.glance_api_app = self._load_paste_app( 'glance-api', flavor=getattr(self, 'api_flavor', ''), conf=getattr(self, 'api_paste_conf', TESTING_API_PASTE_CONF), ) self.http = test_utils.Httplib2WsgiAdapter(self.glance_api_app) def _setup_property_protection(self): self._copy_data_file('property-protections.conf', self.test_dir) self.property_file = os.path.join(self.test_dir, 'property-protections.conf') def _configure_logging(self): self.config(default_log_levels=[ 'amqplib=WARN', 'sqlalchemy=WARN', 'boto=WARN', 'suds=INFO', 'keystone=INFO', 'eventlet.wsgi.server=DEBUG' ]) def _setup_database(self): sql_connection = 'sqlite:////%s/tests.sqlite' % self.test_dir self.config(connection=sql_connection, group='database') glance.db.sqlalchemy.api.clear_db_env() glance_db_env = 'GLANCE_DB_TEST_SQLITE_FILE' if glance_db_env in os.environ: # use the empty db created and cached as a tempfile # instead of spending the time creating a new one db_location = os.environ[glance_db_env] test_utils.execute('cp %s %s/tests.sqlite' % (db_location, self.test_dir)) else: migration.db_sync() # copy the clean db to a temp location so that it # can be reused for future tests (osf, db_location) = tempfile.mkstemp() os.close(osf) test_utils.execute('cp %s/tests.sqlite %s' % (self.test_dir, db_location)) os.environ[glance_db_env] = db_location # cleanup the temp file when the test suite is # complete def _delete_cached_db(): try: os.remove(os.environ[glance_db_env]) except Exception: glance_tests.logger.exception( "Error cleaning up the file %s" % os.environ[glance_db_env]) atexit.register(_delete_cached_db) def _setup_stores(self): image_dir = os.path.join(self.test_dir, "images") self.config(filesystem_store_datadir=image_dir) glance.store.create_stores() def _load_paste_app(self, name, flavor, conf): conf_file_path = os.path.join(self.test_dir, '%s-paste.ini' % name) with open(conf_file_path, 'wb') as conf_file: conf_file.write(conf) conf_file.flush() return config.load_paste_app(name, flavor=flavor, conf_file=conf_file_path) def _connect_registry_client(self): def get_connection_type(self2): def wrapped(*args, **kwargs): return test_utils.HttplibWsgiAdapter(self.glance_registry_app) return wrapped self.stubs.Set(glance.common.client.BaseClient, 'get_connection_type', get_connection_type) def tearDown(self): glance.db.sqlalchemy.api.clear_db_env() super(ApiTest, self).tearDown() glance-2014.1/glance/tests/integration/legacy_functional/__init__.py0000664000175400017540000000000012323736226026701 0ustar jenkinsjenkins00000000000000glance-2014.1/glance/tests/integration/v2/0000775000175400017540000000000012323736427021446 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/tests/integration/v2/test_tasks_api.py0000664000175400017540000004750212323736226025042 0ustar jenkinsjenkins00000000000000# Copyright 2013 Rackspace Hosting # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from glance.api.v2 import tasks import glance.openstack.common.jsonutils as json from glance.tests.integration.v2 import base TENANT1 = '6838eb7b-6ded-434a-882c-b344c77fe8df' TENANT2 = '2c014f32-55eb-467d-8fcb-4bd706012f81' TENANT3 = '5a3e60e8-cfa9-4a9e-a90a-62b42cea92b8' TENANT4 = 'c6c87f25-8a94-47ed-8c83-053c25f42df4' def minimal_task_headers(owner='tenant1'): headers = { 'X-Auth-Token': 'user1:%s:admin' % owner, 'Content-Type': 'application/json', } return headers def _new_task_fixture(**kwargs): task_data = { "type": "import", "input": { "import_from": "/some/file/path", "import_from_format": "qcow2", "image_properties": { 'disk_format': 'vhd', 'container_format': 'ovf' } } } task_data.update(kwargs) return task_data class TestTasksApi(base.ApiTest): def __init__(self, *args, **kwargs): super(TestTasksApi, self).__init__(*args, **kwargs) self.api_flavor = 'fakeauth' self.registry_flavor = 'fakeauth' def _post_new_task(self, **kwargs): task_owner = kwargs['owner'] headers = minimal_task_headers(task_owner) task_data = _new_task_fixture() body_content = json.dumps(task_data) path = "/v2/tasks" response, content = self.http.request(path, 'POST', headers=headers, body=body_content) self.assertEqual(response.status, 201) task = json.loads(content) return task def test_all_task_api(self): # 0. GET /tasks # Verify no tasks path = "/v2/tasks" response, content = self.http.request(path, 'GET', headers=minimal_task_headers()) content_dict = json.loads(content) self.assertEqual(response.status, 200) self.assertFalse(content_dict['tasks']) # 1. GET /tasks/{task_id} # Verify non-existent task task_id = 'NON_EXISTENT_TASK' path = "/v2/tasks/%s" % task_id response, content = self.http.request(path, 'GET', headers=minimal_task_headers()) self.assertEqual(response.status, 404) # 2. POST /tasks # Create a new task task_data = _new_task_fixture() task_owner = 'tenant1' body_content = json.dumps(task_data) path = "/v2/tasks" response, content = self.http.request(path, 'POST', headers= minimal_task_headers(task_owner), body=body_content) self.assertEqual(response.status, 201) data = json.loads(content) task_id = data['id'] self.assertIsNotNone(task_id) self.assertEqual(task_owner, data['owner']) self.assertEqual(task_data['type'], data['type']) self.assertEqual(task_data['input'], data['input']) # 3. GET /tasks/{task_id} # Get an existing task path = "/v2/tasks/%s" % task_id response, content = self.http.request(path, 'GET', headers=minimal_task_headers()) self.assertEqual(response.status, 200) # 4. GET /tasks/{task_id} # Get all tasks (not deleted) path = "/v2/tasks" response, content = self.http.request(path, 'GET', headers=minimal_task_headers()) self.assertEqual(response.status, 200) self.assertIsNotNone(content) data = json.loads(content) self.assertIsNotNone(data) self.assertEqual(1, len(data['tasks'])) #NOTE(venkatesh) find a way to get expected_keys from tasks controller expected_keys = set(['id', 'type', 'owner', 'status', 'created_at', 'updated_at', 'self', 'schema']) task = data['tasks'][0] self.assertEqual(expected_keys, set(task.keys())) self.assertEqual(task_data['type'], task['type']) self.assertEqual(task_owner, task['owner']) self.assertEqual('pending', task['status']) self.assertIsNotNone(task['created_at']) self.assertIsNotNone(task['updated_at']) def test_task_schema_api(self): # 0. GET /schemas/task # Verify schema for task path = "/v2/schemas/task" response, content = self.http.request(path, 'GET', headers=minimal_task_headers()) self.assertEqual(response.status, 200) schema = tasks.get_task_schema() expected_schema = schema.minimal() data = json.loads(content) self.assertIsNotNone(data) self.assertEqual(expected_schema, data) # 1. GET /schemas/tasks # Verify schema for tasks path = "/v2/schemas/tasks" response, content = self.http.request(path, 'GET', headers=minimal_task_headers()) self.assertEqual(response.status, 200) schema = tasks.get_collection_schema() expected_schema = schema.minimal() data = json.loads(content) self.assertIsNotNone(data) self.assertEqual(expected_schema, data) def test_create_new_task(self): # 0. POST /tasks # Create a new task with valid input and type task_data = _new_task_fixture() task_owner = 'tenant1' body_content = json.dumps(task_data) path = "/v2/tasks" response, content = self.http.request(path, 'POST', headers= minimal_task_headers(task_owner), body=body_content) self.assertEqual(response.status, 201) data = json.loads(content) task_id = data['id'] self.assertIsNotNone(task_id) self.assertEqual(task_owner, data['owner']) self.assertEqual(task_data['type'], data['type']) self.assertEqual(task_data['input'], data['input']) # 1. POST /tasks # Create a new task with invalid type # Expect BadRequest(400) Error as response task_data = _new_task_fixture(type='invalid') task_owner = 'tenant1' body_content = json.dumps(task_data) path = "/v2/tasks" response, content = self.http.request(path, 'POST', headers= minimal_task_headers(task_owner), body=body_content) self.assertEqual(response.status, 400) # 1. POST /tasks # Create a new task with invalid input for type 'import' # Expect BadRequest(400) Error as response task_data = _new_task_fixture(input='{something: invalid}') task_owner = 'tenant1' body_content = json.dumps(task_data) path = "/v2/tasks" response, content = self.http.request(path, 'POST', headers= minimal_task_headers(task_owner), body=body_content) self.assertEqual(response.status, 400) def test_tasks_with_filter(self): # 0. GET /v2/tasks # Verify no tasks path = "/v2/tasks" response, content = self.http.request(path, 'GET', headers=minimal_task_headers()) self.assertEqual(response.status, 200) content_dict = json.loads(content) self.assertFalse(content_dict['tasks']) task_ids = [] # 1. POST /tasks with two tasks with status 'pending' and 'processing' # with various attributes task_owner = TENANT1 headers = minimal_task_headers(task_owner) task_data = _new_task_fixture() body_content = json.dumps(task_data) path = "/v2/tasks" response, content = self.http.request(path, 'POST', headers=headers, body=body_content) self.assertEqual(response.status, 201) data = json.loads(content) task_ids.append(data['id']) task_owner = TENANT2 headers = minimal_task_headers(task_owner) task_data = _new_task_fixture() body_content = json.dumps(task_data) path = "/v2/tasks" response, content = self.http.request(path, 'POST', headers=headers, body=body_content) self.assertEqual(response.status, 201) data = json.loads(content) task_ids.append(data['id']) # 2. GET /tasks # Verify two import tasks path = "/v2/tasks" response, content = self.http.request(path, 'GET', headers=minimal_task_headers()) self.assertEqual(response.status, 200) content_dict = json.loads(content) self.assertEqual(2, len(content_dict['tasks'])) # 3. GET /tasks with owner filter # Verify correct task returned with owner params = "owner=%s" % TENANT1 path = "/v2/tasks?%s" % params response, content = self.http.request(path, 'GET', headers=minimal_task_headers()) self.assertEqual(response.status, 200) content_dict = json.loads(content) self.assertEqual(1, len(content_dict['tasks'])) self.assertEqual(TENANT1, content_dict['tasks'][0]['owner']) # Check the same for different owner. params = "owner=%s" % TENANT2 path = "/v2/tasks?%s" % params response, content = self.http.request(path, 'GET', headers=minimal_task_headers()) self.assertEqual(response.status, 200) content_dict = json.loads(content) self.assertEqual(1, len(content_dict['tasks'])) self.assertEqual(TENANT2, content_dict['tasks'][0]['owner']) # 4. GET /tasks with type filter # Verify correct task returned with type params = "type=import" path = "/v2/tasks?%s" % params response, content = self.http.request(path, 'GET', headers=minimal_task_headers()) self.assertEqual(response.status, 200) content_dict = json.loads(content) self.assertEqual(2, len(content_dict['tasks'])) actual_task_ids = [task['id'] for task in content_dict['tasks']] self.assertEqual(set(task_ids), set(actual_task_ids)) # 5. GET /tasks with status filter # Verify correct tasks are returned for status 'pending' params = "status=pending" path = "/v2/tasks?%s" % params response, content = self.http.request(path, 'GET', headers=minimal_task_headers()) self.assertEqual(response.status, 200) content_dict = json.loads(content) self.assertEqual(2, len(content_dict['tasks'])) actual_task_ids = [task['id'] for task in content_dict['tasks']] self.assertEqual(set(task_ids), set(actual_task_ids)) # 6. GET /tasks with status filter # Verify no task are returned for status which is not 'pending' params = "status=success" path = "/v2/tasks?%s" % params response, content = self.http.request(path, 'GET', headers=minimal_task_headers()) self.assertEqual(response.status, 200) content_dict = json.loads(content) self.assertEqual(0, len(content_dict['tasks'])) def test_limited_tasks(self): """ Ensure marker and limit query params work """ # 0. GET /tasks # Verify no tasks path = "/v2/tasks" response, content = self.http.request(path, 'GET', headers=minimal_task_headers()) self.assertEqual(response.status, 200) tasks = json.loads(content) self.assertFalse(tasks['tasks']) task_ids = [] # 1. POST /tasks with three tasks with various attributes task = self._post_new_task(owner=TENANT1) task_ids.append(task['id']) task = self._post_new_task(owner=TENANT2) task_ids.append(task['id']) task = self._post_new_task(owner=TENANT3) task_ids.append(task['id']) # 2. GET /tasks # Verify 3 tasks are returned path = "/v2/tasks" response, content = self.http.request(path, 'GET', headers=minimal_task_headers()) self.assertEqual(response.status, 200) tasks = json.loads(content)['tasks'] self.assertEqual(3, len(tasks)) # 3. GET /tasks with limit of 2 # Verify only two tasks were returned params = "limit=2" path = "/v2/tasks?%s" % params response, content = self.http.request(path, 'GET', headers=minimal_task_headers()) self.assertEqual(response.status, 200) actual_tasks = json.loads(content)['tasks'] self.assertEqual(2, len(actual_tasks)) self.assertEqual(tasks[0]['id'], actual_tasks[0]['id']) self.assertEqual(tasks[1]['id'], actual_tasks[1]['id']) # 4. GET /tasks with marker # Verify only two tasks were returned params = "marker=%s" % tasks[0]['id'] path = "/v2/tasks?%s" % params response, content = self.http.request(path, 'GET', headers=minimal_task_headers()) self.assertEqual(response.status, 200) actual_tasks = json.loads(content)['tasks'] self.assertEqual(2, len(actual_tasks)) self.assertEqual(tasks[1]['id'], actual_tasks[0]['id']) self.assertEqual(tasks[2]['id'], actual_tasks[1]['id']) # 5. GET /tasks with marker and limit # Verify only one task was returned with the correct id params = "limit=1&marker=%s" % tasks[1]['id'] path = "/v2/tasks?%s" % params response, content = self.http.request(path, 'GET', headers=minimal_task_headers()) self.assertEqual(response.status, 200) actual_tasks = json.loads(content)['tasks'] self.assertEqual(1, len(actual_tasks)) self.assertEqual(tasks[2]['id'], actual_tasks[0]['id']) def test_ordered_tasks(self): # 0. GET /tasks # Verify no tasks path = "/v2/tasks" response, content = self.http.request(path, 'GET', headers=minimal_task_headers()) self.assertEqual(response.status, 200) tasks = json.loads(content) self.assertFalse(tasks['tasks']) task_ids = [] # 1. POST /tasks with three tasks with various attributes task = self._post_new_task(owner=TENANT1) task_ids.append(task['id']) task = self._post_new_task(owner=TENANT2) task_ids.append(task['id']) task = self._post_new_task(owner=TENANT3) task_ids.append(task['id']) # 2. GET /tasks with no query params # Verify three tasks sorted by created_at desc # 2. GET /tasks # Verify 3 tasks are returned path = "/v2/tasks" response, content = self.http.request(path, 'GET', headers=minimal_task_headers()) self.assertEqual(response.status, 200) actual_tasks = json.loads(content)['tasks'] self.assertEqual(3, len(actual_tasks)) self.assertEqual(task_ids[2], actual_tasks[0]['id']) self.assertEqual(task_ids[1], actual_tasks[1]['id']) self.assertEqual(task_ids[0], actual_tasks[2]['id']) # 3. GET /tasks sorted by owner asc params = 'sort_key=owner&sort_dir=asc' path = '/v2/tasks?%s' % params response, content = self.http.request(path, 'GET', headers=minimal_task_headers()) self.assertEqual(response.status, 200) expected_task_owners = [TENANT1, TENANT2, TENANT3] expected_task_owners.sort() actual_tasks = json.loads(content)['tasks'] self.assertEqual(3, len(actual_tasks)) self.assertEqual(expected_task_owners, [t['owner'] for t in actual_tasks]) # 4. GET /tasks sorted by owner desc with a marker params = 'sort_key=owner&sort_dir=desc&marker=%s' % task_ids[0] path = '/v2/tasks?%s' % params response, content = self.http.request(path, 'GET', headers=minimal_task_headers()) self.assertEqual(response.status, 200) actual_tasks = json.loads(content)['tasks'] self.assertEqual(2, len(actual_tasks)) self.assertEqual(task_ids[2], actual_tasks[0]['id']) self.assertEqual(task_ids[1], actual_tasks[1]['id']) self.assertEqual(TENANT3, actual_tasks[0]['owner']) self.assertEqual(TENANT2, actual_tasks[1]['owner']) # 5. GET /tasks sorted by owner asc with a marker params = 'sort_key=owner&sort_dir=asc&marker=%s' % task_ids[0] path = '/v2/tasks?%s' % params response, content = self.http.request(path, 'GET', headers=minimal_task_headers()) self.assertEqual(response.status, 200) actual_tasks = json.loads(content)['tasks'] self.assertEqual(0, len(actual_tasks)) def test_delete_task(self): # 0. POST /tasks # Create a new task with valid input and type task_data = _new_task_fixture() task_owner = 'tenant1' body_content = json.dumps(task_data) path = "/v2/tasks" response, content = self.http.request(path, 'POST', headers= minimal_task_headers(task_owner), body=body_content) self.assertEqual(response.status, 201) data = json.loads(content) task_id = data['id'] # 1. DELETE on /tasks/{task_id} # Attempt to delete a task path = "/v2/tasks/%s" % task_id response, content = self.http.request(path, 'DELETE', headers=minimal_task_headers()) self.assertEqual(response.status, 405) self.assertEqual('GET', response.webob_resp.headers.get('Allow')) self.assertEqual(('GET',), response.webob_resp.allow) self.assertEqual(('GET',), response.allow) # 2. GET /tasks/{task_id} # Ensure that methods mentioned in the Allow header work path = "/v2/tasks/%s" % task_id response, content = self.http.request(path, 'GET', headers=minimal_task_headers()) self.assertEqual(response.status, 200) self.assertIsNotNone(content) glance-2014.1/glance/tests/integration/v2/base.py0000664000175400017540000001572712323736226022743 0ustar jenkinsjenkins00000000000000# Copyright 2013 Rackspace Hosting # 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 atexit import os.path import tempfile import fixtures from oslo.config import cfg import glance.common.client from glance.common import config from glance.db import migration import glance.db.sqlalchemy.api import glance.registry.client.v1.client import glance.store from glance import tests as glance_tests from glance.tests import utils as test_utils TESTING_API_PASTE_CONF = """ [pipeline:glance-api] pipeline = versionnegotiation gzip unauthenticated-context rootapp [pipeline:glance-api-caching] pipeline = versionnegotiation gzip unauthenticated-context cache rootapp [pipeline:glance-api-cachemanagement] pipeline = versionnegotiation gzip unauthenticated-context cache cache_manage rootapp [pipeline:glance-api-fakeauth] pipeline = versionnegotiation gzip fakeauth context rootapp [pipeline:glance-api-noauth] pipeline = versionnegotiation gzip context rootapp [composite:rootapp] paste.composite_factory = glance.api:root_app_factory /: apiversions /v1: apiv1app /v2: apiv2app [app:apiversions] paste.app_factory = glance.api.versions:create_resource [app:apiv1app] paste.app_factory = glance.api.v1.router:API.factory [app:apiv2app] paste.app_factory = glance.api.v2.router:API.factory [filter:versionnegotiation] paste.filter_factory = glance.api.middleware.version_negotiation:VersionNegotiationFilter.factory [filter:gzip] paste.filter_factory = glance.api.middleware.gzip:GzipMiddleware.factory [filter:cache] paste.filter_factory = glance.api.middleware.cache:CacheFilter.factory [filter:cache_manage] paste.filter_factory = glance.api.middleware.cache_manage:CacheManageFilter.factory [filter:context] paste.filter_factory = glance.api.middleware.context:ContextMiddleware.factory [filter:unauthenticated-context] paste.filter_factory = glance.api.middleware.context:UnauthenticatedContextMiddleware.factory [filter:fakeauth] paste.filter_factory = glance.tests.utils:FakeAuthMiddleware.factory """ TESTING_REGISTRY_PASTE_CONF = """ [pipeline:glance-registry] pipeline = unauthenticated-context registryapp [pipeline:glance-registry-fakeauth] pipeline = fakeauth context registryapp [app:registryapp] paste.app_factory = glance.registry.api.v1:API.factory [filter:context] paste.filter_factory = glance.api.middleware.context:ContextMiddleware.factory [filter:unauthenticated-context] paste.filter_factory = glance.api.middleware.context:UnauthenticatedContextMiddleware.factory [filter:fakeauth] paste.filter_factory = glance.tests.utils:FakeAuthMiddleware.factory """ CONF = cfg.CONF CONF.import_opt('filesystem_store_datadir', 'glance.store.filesystem') class ApiTest(test_utils.BaseTestCase): def setUp(self): super(ApiTest, self).setUp() self.test_dir = self.useFixture(fixtures.TempDir()).path self._configure_logging() self._setup_database() self._setup_stores() self._setup_property_protection() self.glance_registry_app = self._load_paste_app( 'glance-registry', flavor=getattr(self, 'registry_flavor', ''), conf=getattr(self, 'registry_paste_conf', TESTING_REGISTRY_PASTE_CONF), ) self._connect_registry_client() self.glance_api_app = self._load_paste_app( 'glance-api', flavor=getattr(self, 'api_flavor', ''), conf=getattr(self, 'api_paste_conf', TESTING_API_PASTE_CONF), ) self.http = test_utils.Httplib2WsgiAdapter(self.glance_api_app) def _setup_property_protection(self): self._copy_data_file('property-protections.conf', self.test_dir) self.property_file = os.path.join(self.test_dir, 'property-protections.conf') def _configure_logging(self): self.config(default_log_levels=[ 'amqplib=WARN', 'sqlalchemy=WARN', 'boto=WARN', 'suds=INFO', 'keystone=INFO', 'eventlet.wsgi.server=DEBUG' ]) def _setup_database(self): sql_connection = 'sqlite:////%s/tests.sqlite' % self.test_dir self.config(connection=sql_connection, group='database') glance.db.sqlalchemy.api.clear_db_env() glance_db_env = 'GLANCE_DB_TEST_SQLITE_FILE' if glance_db_env in os.environ: # use the empty db created and cached as a tempfile # instead of spending the time creating a new one db_location = os.environ[glance_db_env] test_utils.execute('cp %s %s/tests.sqlite' % (db_location, self.test_dir)) else: migration.db_sync() # copy the clean db to a temp location so that it # can be reused for future tests (osf, db_location) = tempfile.mkstemp() os.close(osf) test_utils.execute('cp %s/tests.sqlite %s' % (self.test_dir, db_location)) os.environ[glance_db_env] = db_location # cleanup the temp file when the test suite is # complete def _delete_cached_db(): try: os.remove(os.environ[glance_db_env]) except Exception: glance_tests.logger.exception( "Error cleaning up the file %s" % os.environ[glance_db_env]) atexit.register(_delete_cached_db) def _setup_stores(self): image_dir = os.path.join(self.test_dir, "images") self.config(filesystem_store_datadir=image_dir) glance.store.create_stores() def _load_paste_app(self, name, flavor, conf): conf_file_path = os.path.join(self.test_dir, '%s-paste.ini' % name) with open(conf_file_path, 'wb') as conf_file: conf_file.write(conf) conf_file.flush() return config.load_paste_app(name, flavor=flavor, conf_file=conf_file_path) def _connect_registry_client(self): def get_connection_type(self2): def wrapped(*args, **kwargs): return test_utils.HttplibWsgiAdapter(self.glance_registry_app) return wrapped self.stubs.Set(glance.common.client.BaseClient, 'get_connection_type', get_connection_type) def tearDown(self): glance.db.sqlalchemy.api.clear_db_env() super(ApiTest, self).tearDown() glance-2014.1/glance/tests/integration/v2/__init__.py0000664000175400017540000000000012323736226023542 0ustar jenkinsjenkins00000000000000glance-2014.1/glance/tests/integration/__init__.py0000664000175400017540000000000012323736226023213 0ustar jenkinsjenkins00000000000000glance-2014.1/glance/tests/__init__.py0000664000175400017540000000212512323736230020675 0ustar jenkinsjenkins00000000000000# Copyright 2010-2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # See http://code.google.com/p/python-nose/issues/detail?id=373 # The code below enables tests to work with i18n _() blocks import __builtin__ setattr(__builtin__, '_', lambda x: x) # Set up logging to output debugging import logging logger = logging.getLogger() hdlr = logging.FileHandler('run_tests.log', 'w') formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s') hdlr.setFormatter(formatter) logger.addHandler(hdlr) logger.setLevel(logging.DEBUG) glance-2014.1/glance/locale/0000775000175400017540000000000012323736427016671 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/he/0000775000175400017540000000000012323736427017265 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/he/LC_MESSAGES/0000775000175400017540000000000012323736427021052 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/he/LC_MESSAGES/glance.po0000664000175400017540000030214512323736226022645 0ustar jenkinsjenkins00000000000000# Hebrew translations for glance. # Copyright (C) 2014 ORGANIZATION # This file is distributed under the same license as the glance project. # # Translators: msgid "" msgstr "" "Project-Id-Version: Glance\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2014-01-28 06:02+0000\n" "Last-Translator: openstackjenkins \n" "Language-Team: Hebrew " "(http://www.transifex.com/projects/p/openstack/language/he/)\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/pt/0000775000175400017540000000000012323736427017314 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/pt/LC_MESSAGES/0000775000175400017540000000000012323736427021101 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/pt/LC_MESSAGES/glance.po0000664000175400017540000030215512323736226022675 0ustar jenkinsjenkins00000000000000# Portuguese translations for glance. # Copyright (C) 2013 ORGANIZATION # This file is distributed under the same license as the glance project. # # Translators: msgid "" msgstr "" "Project-Id-Version: Glance\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2013-08-30 08:49+0000\n" "Last-Translator: openstackjenkins \n" "Language-Team: Portuguese " "(http://www.transifex.com/projects/p/openstack/language/pt/)\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/id/0000775000175400017540000000000012323736427017265 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/id/LC_MESSAGES/0000775000175400017540000000000012323736427021052 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/id/LC_MESSAGES/glance.po0000664000175400017540000030214612323736226022646 0ustar jenkinsjenkins00000000000000# Indonesian translations for glance. # Copyright (C) 2013 ORGANIZATION # This file is distributed under the same license as the glance project. # # Translators: msgid "" msgstr "" "Project-Id-Version: Glance\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2013-08-30 08:49+0000\n" "Last-Translator: openstackjenkins \n" "Language-Team: Indonesian " "(http://www.transifex.com/projects/p/openstack/language/id/)\n" "Plural-Forms: nplurals=1; plural=0\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/sv/0000775000175400017540000000000012323736427017321 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/sv/LC_MESSAGES/0000775000175400017540000000000012323736427021106 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/sv/LC_MESSAGES/glance.po0000664000175400017540000030214712323736226022703 0ustar jenkinsjenkins00000000000000# Swedish translations for glance. # Copyright (C) 2013 ORGANIZATION # This file is distributed under the same license as the glance project. # # Translators: msgid "" msgstr "" "Project-Id-Version: Glance\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2013-11-21 06:05+0000\n" "Last-Translator: openstackjenkins \n" "Language-Team: Swedish " "(http://www.transifex.com/projects/p/openstack/language/sv/)\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/nl_NL/0000775000175400017540000000000012323736427017673 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/nl_NL/LC_MESSAGES/0000775000175400017540000000000012323736427021460 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/nl_NL/LC_MESSAGES/glance.po0000664000175400017540000030220212323736226023245 0ustar jenkinsjenkins00000000000000# Dutch (Netherlands) translations for glance. # Copyright (C) 2013 ORGANIZATION # This file is distributed under the same license as the glance project. # # Translators: msgid "" msgstr "" "Project-Id-Version: Glance\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2013-08-30 08:49+0000\n" "Last-Translator: openstackjenkins \n" "Language-Team: Dutch (Netherlands) " "(http://www.transifex.com/projects/p/openstack/language/nl_NL/)\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/eu_ES/0000775000175400017540000000000012323736427017671 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/eu_ES/LC_MESSAGES/0000775000175400017540000000000012323736427021456 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/eu_ES/LC_MESSAGES/glance.po0000664000175400017540000030217012323736226023247 0ustar jenkinsjenkins00000000000000# Basque (Spain) translations for glance. # Copyright (C) 2013 ORGANIZATION # This file is distributed under the same license as the glance project. # # Translators: msgid "" msgstr "" "Project-Id-Version: Glance\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2013-11-21 06:05+0000\n" "Last-Translator: openstackjenkins \n" "Language-Team: Basque (Spain) " "(http://www.transifex.com/projects/p/openstack/language/eu_ES/)\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/pl_PL/0000775000175400017540000000000012323736427017677 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/pl_PL/LC_MESSAGES/0000775000175400017540000000000012323736427021464 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/pl_PL/LC_MESSAGES/glance.po0000664000175400017540000030230412323736226023254 0ustar jenkinsjenkins00000000000000# Polish (Poland) translations for glance. # Copyright (C) 2013 ORGANIZATION # This file is distributed under the same license as the glance project. # # Translators: msgid "" msgstr "" "Project-Id-Version: Glance\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2013-08-30 08:49+0000\n" "Last-Translator: openstackjenkins \n" "Language-Team: Polish (Poland) " "(http://www.transifex.com/projects/p/openstack/language/pl_PL/)\n" "Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && " "(n%100<10 || n%100>=20) ? 1 : 2)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "Wynik był %s" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/sl_SI/0000775000175400017540000000000012323736427017702 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/sl_SI/LC_MESSAGES/0000775000175400017540000000000012323736427021467 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/sl_SI/LC_MESSAGES/glance.po0000664000175400017540000030227312323736226023264 0ustar jenkinsjenkins00000000000000# Slovenian (Slovenia) translations for glance. # Copyright (C) 2013 ORGANIZATION # This file is distributed under the same license as the glance project. # # Translators: msgid "" msgstr "" "Project-Id-Version: Glance\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2013-08-30 08:49+0000\n" "Last-Translator: openstackjenkins \n" "Language-Team: Slovenian (Slovenia) " "(http://www.transifex.com/projects/p/openstack/language/sl_SI/)\n" "Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 " "|| n%100==4 ? 2 : 3)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/en_US/0000775000175400017540000000000012323736427017702 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/en_US/LC_MESSAGES/0000775000175400017540000000000012323736427021467 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/en_US/LC_MESSAGES/glance.po0000664000175400017540000035513412323736226023270 0ustar jenkinsjenkins00000000000000# English (United States) translations for glance. # Copyright (C) 2013 ORGANIZATION # This file is distributed under the same license as the glance project. # # Translators: msgid "" msgstr "" "Project-Id-Version: Glance\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2013-04-10 10:09+0000\n" "Last-Translator: FULL NAME \n" "Language-Team: en_US \n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "An error occurred during image.send notification: %(err)s" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "Image storage media is full: %s" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "Insufficient permissions on image storage media: %s" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "custom properties (%(props)s) conflict with base properties" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "The amount of time in seconds to delay before performing a delete." #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "Failed to find image to delete: %(e)s" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "Daemon Shutdown on KeyboardInterrupt" #: glance/scrubber.py:380 msgid "Running application" msgstr "Running application" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "Next run scheduled in %s seconds" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "Getting images deleted before %s" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "You cannot get image member for %s" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "You cannot delete image member for %s" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "You cannot add image member for %s" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "You cannot update image member %s" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "You are not permitted to create images owned by '%s'." #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "You are not permitted to create image members for the image." #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "Public images do not have members." #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "You are not permitted to modify locations for this image." #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "You are not permitted to modify '%s' on this image." #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "You are not permitted to modify this image." #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "You are not permitted to modify tags on this image." #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "You are not permitted to delete this image." #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "You are not permitted to upload data for this image." #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "Corrupt image download for image %(image_id)s" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "The location of the policy file." #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "The default policy to use." #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "Loaded %(rule_type)spolicy rules: %(text_rules)s" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "Unable to find policy file" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "Loading policy from %s" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "Initialized image cache middleware" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "Cache hit for image '%s'" #: glance/api/middleware/cache.py:132 #, python-format msgid "" "Image cache contained image file for image '%s', however the registry did" " not contain metadata for that image!" msgstr "" "Image cache contained image file for image '%s', however the registry did" " not contain metadata for that image!" #: glance/api/middleware/cache.py:230 #, python-format msgid "could not find %s" msgstr "could not find %s" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "Removing image %s from cache" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "Checksum header is missing." #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "Initialized image cache management middleware" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "Role used to identify an authenticated user as administrator." #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "Unable to retrieve request id from context" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "Invalid service catalog json." #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "Determining version of request: %(method)s %(path)s Accept: %(accept)s" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "Using media-type versioning" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "Using url versioning" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "Unknown version. Returning version choices." #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "Matched version: v%d" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "Image with identifier %s not found" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "Forbidden image access" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "Image %s is not active" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "Store for image_id not found: %s" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "Image name too long: %d" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "External sourcing not supported for store %s" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "An image with identifier %s already exists" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "Failed to reserve image. Got error: %(e)s" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "Forbidden to reserve image." #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "Copy from external source failed: %s" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "Content-Type must be application/octet-stream" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "Setting image %s to status 'saving'" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "Uploading image data for image %(image_id)s to %(scheme)s store" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "Failed to activate image. Got error: %(e)s" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "Triggering asynchronous copy from external source" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "Forbidden to update deleted image." #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "Cannot upload to an unqueued image" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "Attempted to update Location field for an image not in queued status." #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "Failed to update image metadata. Got error: %(e)s" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "Failed to find image to update: %(e)s" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "Forbidden to update image: %(e)s" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "Image is protected" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "Forbidden to delete image: %(e)s" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "Store for scheme %s not found" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "Denying attempt to upload image larger than %d bytes." #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "No authenticated user" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "Unauthorized image access" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "Attempt to upload duplicate image: %s" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "Forbidden upload attempt: %s" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "Not allowed to upload image data for image %s" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "Failed to upload image data due to HTTP error" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "Failed to upload image data due to internal error" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "Body expected in request." #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "Member to be added not specified" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "Status not specified" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "An identifier for the image member (tenantId)" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "An identifier for the image" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "Date and time of image member creation" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "Date and time of last modification of image member" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "The status of this image member" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "Property %s does not exist." #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "Property %s already present." #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "Property %s may not be removed." #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "Unable to find '%s' in JSON Schema change" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "Pointer `%s` does not start with \"/\"." #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "Pointer `%s` contains \"~\" not part of a recognized escape sequence." #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "Operation \"%s\" requires a member named \"value\"." #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "Unrecognized JSON Schema draft version" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "Request body must be a JSON array of operation objects." #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "Operations must be JSON objects." #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "limit param must be an integer" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "limit param must be positive" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "Invalid sort direction: %s" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "Invalid status: %s" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "Invalid visibility value: %s" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "Descriptive name for the image" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "Scope of image accessibility" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "If true, image will not be deletable." #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "List of strings related to the image" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "Amount of ram (in MB) required to boot image." #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "Amount of disk space (in GB) required to boot image." #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" "Could not find schema properties file %s. Continuing without custom " "properties" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "Invalid marker format" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "Unexpected response: %s" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "Unknown auth strategy '%s'" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "Encountered service with no \"type\": %s" #: glance/common/client.py:240 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 "" "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" #: glance/common/client.py:248 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 "" "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" #: glance/common/client.py:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "The key file you specified %s does not exist" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "The cert file you specified %s does not exist" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "The CA file you specified %s does not exist" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "Configuring from URL: %s" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "Appending doc_root %(doc_root)s to URL %(url)s" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "Constructed URL: %s" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "Name of the paste configuration file." #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" "Whether to allow users to specify image properties beyond what the image " "schema provides" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "Python module path of data access API" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "Maximum permissible number of items that could be returned by a request" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "The hostname/IP of the pydev process listening for debug connections" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "The port on which a pydev process is listening for connections." #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "Loading %(app_name)s from %(conf_file)s" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "An unknown exception occurred" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "Missing required credential: %(required)s" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "An object with the specified identifier was not found." #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "Unknown scheme '%(scheme)s' found in URI" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "The Store URI was malformed." #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "An object with the same identifier already exists." #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "There is not enough disk space on the image storage media." #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "Permission to write image storage media denied." #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "Connect error/bad request to Auth service at URL %(url)s." #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "Auth service at URL %(url)s not found." #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "Authorization failed." #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "You are not authenticated." #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "You are not authorized to complete this action." #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "Image %(image_id)s is protected and cannot be deleted." #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "Data supplied was not valid." #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "Sort key supplied was not valid." #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "Unable to filter using the specified range." #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "Attribute '%(property)s' is read-only." #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "Attribute '%(property)s' is reserved." #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "Redirecting to %(uri)s for authorization." #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "There was an error connecting to a server" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "There was an error configuring the client." #: glance/common/exception.py:170 #, 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 "" "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" #: glance/common/exception.py:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "The request returned 500 Internal Server Error." #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "Invalid content type %(content_type)s" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "Registry was not configured correctly on API server. Reason: %(reason)s" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "Deleting images from this store is not supported." #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "Configuration for store failed. Adding images to this store is disabled." #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "Maximum redirects (%(redirects)s) was exceeded." #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "Received invalid HTTP redirect." #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "Response from Keystone does not contain a Glance endpoint." #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "Server worker creation failed: %(reason)s." #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "Unable to load schema: %(reason)s" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "Provided object does not match schema '%(schema)s': %(reason)s" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "Provided header feature is unsupported: %(feature)s" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "The provided image is too large." #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "No image data could be found" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "Error: cooperative_iter exception %s" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "Read-only access" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "Invalid backend: %s" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" "Address to bind the server. Useful when selecting a particular network " "interface." #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "The port on which the server will listen." #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "The backlog value that will be used when creating the TCP listener socket." #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "CA certificate file to use to verify connecting clients." #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "Certificate file to use when starting API server securely." #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "Private key file to use when starting API server securely." #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" "The number of child process workers that will be created to service API " "requests." #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 msgid "" "When running server in SSL mode, you must specify both a cert_file and " "key_file option value in your configuration file" msgstr "" "When running server in SSL mode, you must specify both a cert_file and " "key_file option value in your configuration file" #: glance/common/wsgi.py:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "Starting %d workers" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "Removing dead child %s" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "Not respawning child %d, cannot recover from termination" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "All workers have terminated. Exiting" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "Caught keyboard interrupt. Exiting." #: glance/common/wsgi.py:278 msgid "Exited" msgstr "Exited" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "Child %d exiting normally" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "Started child %s" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "Starting single process server" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "Malformed JSON in request body." #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "Returning %(funcname)s: %(output)s" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "Unable to filter on a range with a non-numeric value." #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "Could not find image %s" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "Unable to get deleted image" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "Unable to get unowned image" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "Attempted to modify image user did not own." #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "You do not own this image" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "Id not in sort_keys; is sort_keys unique?" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "Unknown sort direction, must be 'desc' or 'asc'" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "creating table %(table)s" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "dropping table %(table)s" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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 "" "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" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "Badly formed credentials '%(creds)s' in Swift URI" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "Badly formed credentials in Swift URI." #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "Property %s must be set prior to saving data." #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "Properties %s must be set prior to saving data." #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "Status must be \"pending\", \"accepted\" or \"rejected\"." #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "The driver to use for image cache management." #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "The maximum size in bytes that the cache can use." #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "Base directory that the Image Cache uses." #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "Image cache loaded driver '%s'." #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "Defaulting to SQLite driver." #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "Image cache has free space, skipping prune..." #: glance/image_cache/__init__.py:178 #, python-format msgid "" "Image cache currently %(overage)d bytes over max size. Starting prune to " "max size of %(max_size)d " msgstr "" "Image cache currently %(overage)d bytes over max size. Starting prune to " "max size of %(max_size)d " #: glance/image_cache/__init__.py:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "Pruning '%(image_id)s' to free %(size)d bytes" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "Tee'ing image '%s' into cache" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "Checksum verification failed. Aborted caching of image '%s'." #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "Image '%s' is not active. Not caching." #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "No metadata found for image '%s'" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "Caching image '%s'" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "Nothing to prefetch." #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "Found %d images to prefetch" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "Failed to successfully cache all images in queue." #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "Successfully cached all %d images" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "Failed to read %s from config" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" "The path to the sqlite file database that will be used for image cache " "management." #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "Failed to initialize the image cache database. Got error: %s" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "Gathering cached image entries." #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "Error executing SQLite call. Got error: %s" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "Not queueing image '%s'. Already cached." #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "Not queueing image '%s'. Already being written to cache" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "Not queueing image '%s'. Already queued." #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "Removed invalid cache file %s" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "Removed stalled cache file %s" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "Deleting image cache file '%s'" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, python-format msgid "Cached image file '%s' doesn't exist, unable to delete" msgstr "Cached image file '%s' doesn't exist, unable to delete" #: 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 "" "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." #: glance/image_cache/drivers/xattr.py:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "Removing image '%s' from queue after caching it." #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "Queueing image '%s'." #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "No grace period, reaping '%(path)s' immediately" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "Reaped %(reaped)s %(entry_type)s cache entries" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "Deprecated: %s" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "syslog facility must be one of: %s" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "Fatal call to deprecated config: %(msg)s" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "Failed to understand rule %(rule)s" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "No handler for matches of kind %s" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "Failed to understand rule %(rule)r" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "Address to find the registry server." #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "Port the registry server is listening on." #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "Invalid marker. Image could not be found." #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "Access denied to image %(id)s but returning 'not found'" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "Returning image list" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "Returning detailed image list" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "Unrecognized changes-since value" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "protected must be True, or False" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "Unsupported sort_key. Acceptable values: %s" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "Unsupported sort_dir. Acceptable values: %s" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "is_public must be None, True, or False" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "Successfully retrieved image %(id)s" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "Image %(id)s not found" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "Successfully deleted image %(id)s" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "Delete denied for public image %(id)s" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "Rejecting image creation request for invalid image id '%(bad_id)s'" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "Invalid image id format" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "Successfully created image %(id)s" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "Image with identifier %s already exists!" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "Failed to add image metadata. Got error: %(e)s" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "Updating image %(id)s with metadata: %(image_data)r" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "Updating metadata for image %(id)s" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "Update denied for public image %(id)s" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "Returning member list for image %(id)s" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "User lacks permission to share image %(id)s" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "No permission to share that image" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "Invalid membership association specified for image %(id)s" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "Invalid membership association: %s" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "Successfully updated memberships for image %(id)s" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "Successfully updated a membership for image %(id)s" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "%(id)s is not a member of image %(image_id)s" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "Membership could not be found." #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "Successfully deleted a membership from image %(id)s" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "Member %(id)s not found" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "Returning list of images shared with member %(id)s" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" "The protocol to use for communication with the registry server. Either " "http or https." #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "The path to the key file to use in SSL connections to the registry server." #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" "The path to the cert file to use in SSL connections to the registry " "server." #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "The administrators user name." #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "The administrators password." #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "The URL to the keystone service." #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "The strategy to use for authentication." #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "The region for the authentication service." #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "Configuration option was not valid" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "Could not find required configuration option" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "Adding image metadata..." #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "Updating image metadata for image %s..." #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "Deleting image metadata for image %s..." #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "Registry client request %(method)s %(action)s raised %(exc_name)s" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" "List of which store classes and store class locations are currently known" " to glance at startup." #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "Turn on/off delayed delete." #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "Skipping store.set_acls... not implemented." #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "Failed to configure store correctly: %s Disabling add method." #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "Directory to which the Filesystem backend store writes images." #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "No path specified in URI: %s" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "Directory to write image files does not exist (%s). Creating." #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "Unable to create datadir: %s" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "Image file %s not found" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "Found image at %s. Returning in ChunkedFile." #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "Found image at %s." #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "Deleting image at %(fn)s" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "You cannot delete file %s" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "Image file %s does not exist" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "Image file %s already exists!" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "Could not find %(param)s in configuration options." #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "Credentials '%s' not well-formatted." #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "No address specified in HTTP URL" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "HTTP URL returned a %s status code." #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "RADOS pool in which images are stored." #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "URI must start with rbd://" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "Invalid URI: %(uri)s: %(reason)s" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "URI contains non-ascii characters" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "URI must have exactly 1 or 4 components" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "URI cannot contain empty components" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "RBD image %s does not exist" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "Error in store configuration: %s" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "RBD image %s already exists" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "The host where the S3 server is listening." #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "The S3 query token access key." #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "The S3 query token secret key." #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "The S3 bucket to be used to store the Glance data." #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." #: glance/store/s3.py:115 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 "" "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" #: glance/store/s3.py:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "Badly formed S3 credentials %s" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "Badly formed S3 URI. Missing s3 service URL." #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "Badly formed S3 URI: %s" #: glance/store/s3.py:307 #, 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 "" "Retrieved image object from S3 using (s3_host=%(s3_host)s, " "access_key=%(accesskey)s, bucket=%(bucket)s, key=%(obj_name)s)" #: glance/store/s3.py:367 #, python-format msgid "S3 already has an image at location %s" msgstr "S3 already has an image at location %s" #: glance/store/s3.py:371 #, 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 "" "Adding image object to S3 using (s3_host=%(s3_host)s, " "access_key=%(access_key)s, bucket=%(bucket)s, key=%(obj_name)s)" #: glance/store/s3.py:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "Writing request body file to temporary file for %s" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "Uploading temporary file to S3 for %s" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" #: glance/store/s3.py:442 #, 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 "" "Deleting image object from S3 using (s3_host=%(s3_host)s, " "access_key=%(accesskey)s, bucket=%(bucket)s, key=%(obj_name)s)" #: glance/store/s3.py:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "Could not find key %(obj)s in bucket %(bucket)s" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "Whether to use ServiceNET to communicate with the Swift storage servers." #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "The address where the Swift authentication service is listening." #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" "Auth key for the user authenticating against the Swift authentication " "service." #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" "Container within the account that the account should use for storing " "images in Swift." #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" "A boolean value that determines if we create the container if it does not" " exist." #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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 "" "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" #: glance/store/swift.py:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "Invalid store URI: %(reason)s" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "Badly formed Swift URI." #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "Deleting chunk %s" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "Adding image object '%(obj_name)s' to Swift" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "Cannot determine image size. Adding as a segmented object to Swift." #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(chunk_id)d/%(total_chunks)s) of length " "%(bytes_read)d to Swift returning MD5 of content: %(chunk_etag)s" msgstr "" "Wrote chunk %(chunk_name)s (%(chunk_id)d/%(total_chunks)s) of length " "%(bytes_read)d to Swift returning MD5 of content: %(chunk_etag)s" #: glance/store/swift.py:461 msgid "Deleting final zero-length chunk" msgstr "Deleting final zero-length chunk" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "Swift already has an image at this location" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "Swift could not find image at URI." #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" #: glance/store/swift.py:566 #, 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 "" "The container %(container)s does not exist in Swift. Please set the " "swift_store_create_container_on_put optionto add container to Swift " "automatically." #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "Location is missing user:password information." #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "Badly formed tenant:user '%(user)s' in Swift URI" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "Multi-tenant Swift storage requires a context." #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "Multi-tenant Swift storage requires a service catalog." #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "location: %s data lost" glance-2014.1/glance/locale/es_MX/0000775000175400017540000000000012323736427017704 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/es_MX/LC_MESSAGES/0000775000175400017540000000000012323736427021471 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/es_MX/LC_MESSAGES/glance.po0000664000175400017540000030217412323736226023266 0ustar jenkinsjenkins00000000000000# Spanish (Mexico) translations for glance. # Copyright (C) 2013 ORGANIZATION # This file is distributed under the same license as the glance project. # # Translators: msgid "" msgstr "" "Project-Id-Version: Glance\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2013-08-30 08:49+0000\n" "Last-Translator: openstackjenkins \n" "Language-Team: Spanish (Mexico) " "(http://www.transifex.com/projects/p/openstack/language/es_MX/)\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/cs/0000775000175400017540000000000012323736427017276 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/cs/LC_MESSAGES/0000775000175400017540000000000012323736427021063 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/cs/LC_MESSAGES/glance.po0000664000175400017540000030222412323736226022654 0ustar jenkinsjenkins00000000000000# Czech translations for PROJECT. # Copyright (C) 2012 ORGANIZATION # This file is distributed under the same license as the PROJECT project. # FIRST AUTHOR , 2012. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2012-04-26 17:39+0800\n" "Last-Translator: FULL NAME \n" "Language-Team: cs \n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/ur/0000775000175400017540000000000012323736427017317 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/ur/LC_MESSAGES/0000775000175400017540000000000012323736427021104 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/ur/LC_MESSAGES/glance.po0000664000175400017540000030214112323736226022673 0ustar jenkinsjenkins00000000000000# Urdu translations for glance. # Copyright (C) 2013 ORGANIZATION # This file is distributed under the same license as the glance project. # # Translators: msgid "" msgstr "" "Project-Id-Version: Glance\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2013-10-28 06:02+0000\n" "Last-Translator: openstackjenkins \n" "Language-Team: Urdu " "(http://www.transifex.com/projects/p/openstack/language/ur/)\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/da/0000775000175400017540000000000012323736427017255 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/da/LC_MESSAGES/0000775000175400017540000000000012323736427021042 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/da/LC_MESSAGES/glance.po0000664000175400017540000030211012323736226022625 0ustar jenkinsjenkins00000000000000# Danish translations for PROJECT. # Copyright (C) 2012 ORGANIZATION # This file is distributed under the same license as the PROJECT project. # FIRST AUTHOR , 2012. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2012-04-26 17:39+0800\n" "Last-Translator: FULL NAME \n" "Language-Team: da \n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/hu/0000775000175400017540000000000012323736427017305 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/hu/LC_MESSAGES/0000775000175400017540000000000012323736427021072 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/hu/LC_MESSAGES/glance.po0000664000175400017540000030215312323736226022664 0ustar jenkinsjenkins00000000000000# Hungarian translations for glance. # Copyright (C) 2013 ORGANIZATION # This file is distributed under the same license as the glance project. # # Translators: msgid "" msgstr "" "Project-Id-Version: Glance\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2013-08-30 08:49+0000\n" "Last-Translator: openstackjenkins \n" "Language-Team: Hungarian " "(http://www.transifex.com/projects/p/openstack/language/hu/)\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/zh_HK/0000775000175400017540000000000012323736427017674 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/zh_HK/LC_MESSAGES/0000775000175400017540000000000012323736427021461 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/zh_HK/LC_MESSAGES/glance.po0000664000175400017540000030222212323736226023250 0ustar jenkinsjenkins00000000000000# Chinese (Traditional, Hong Kong SAR China) translations for glance. # Copyright (C) 2013 ORGANIZATION # This file is distributed under the same license as the glance project. # # Translators: msgid "" msgstr "" "Project-Id-Version: Glance\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2013-08-30 08:49+0000\n" "Last-Translator: openstackjenkins \n" "Language-Team: Chinese (Hong Kong) " "(http://www.transifex.com/projects/p/openstack/language/zh_HK/)\n" "Plural-Forms: nplurals=1; plural=0\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/ms/0000775000175400017540000000000012323736427017310 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/ms/LC_MESSAGES/0000775000175400017540000000000012323736427021075 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/ms/LC_MESSAGES/glance.po0000664000175400017540000030213412323736226022666 0ustar jenkinsjenkins00000000000000# Malay translations for glance. # Copyright (C) 2013 ORGANIZATION # This file is distributed under the same license as the glance project. # # Translators: msgid "" msgstr "" "Project-Id-Version: Glance\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2013-08-30 08:49+0000\n" "Last-Translator: openstackjenkins \n" "Language-Team: Malay " "(http://www.transifex.com/projects/p/openstack/language/ms/)\n" "Plural-Forms: nplurals=1; plural=0\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/tl/0000775000175400017540000000000012323736427017310 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/tl/LC_MESSAGES/0000775000175400017540000000000012323736427021075 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/tl/LC_MESSAGES/glance.po0000664000175400017540000030211112323736226022661 0ustar jenkinsjenkins00000000000000# Tagalog translations for PROJECT. # Copyright (C) 2012 ORGANIZATION # This file is distributed under the same license as the PROJECT project. # FIRST AUTHOR , 2012. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2012-04-26 17:40+0800\n" "Last-Translator: FULL NAME \n" "Language-Team: tl \n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/tr_TR/0000775000175400017540000000000012323736427017723 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/tr_TR/LC_MESSAGES/0000775000175400017540000000000012323736427021510 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/tr_TR/LC_MESSAGES/glance.po0000664000175400017540000030301112323736226023274 0ustar jenkinsjenkins00000000000000# Turkish (Turkey) translations for glance. # Copyright (C) 2013 ORGANIZATION # This file is distributed under the same license as the glance project. # # Translators: msgid "" msgstr "" "Project-Id-Version: Glance\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2013-08-30 08:49+0000\n" "Last-Translator: openstackjenkins \n" "Language-Team: Turkish (Turkey) " "(http://www.transifex.com/projects/p/openstack/language/tr_TR/)\n" "Plural-Forms: nplurals=1; plural=0\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "Sınır parametresi tam sayı olmak zorunda" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "Sınır parametresi pozitif olmak zorunda" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "Geçersiz backend: %s" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "syslog servisi bunlardan biri olmak zorundadır: %s" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "utils.execute için bilinmeyen anahtar kelime argümanları: %r" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "Çalışan komut(alt süreç): %s" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "Sonuç %s" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "%r hatalı. Yeniden deneniyor." #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "Çalışan komut(SSH): %s" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "SSH üzerinde ortam desteklenmemektedir." #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "SSH üzerinde process_input desteklenmemektedir." #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/sw_KE/0000775000175400017540000000000012323736427017701 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/sw_KE/LC_MESSAGES/0000775000175400017540000000000012323736427021466 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/sw_KE/LC_MESSAGES/glance.po0000664000175400017540000030217212323736226023261 0ustar jenkinsjenkins00000000000000# Swahili (Kenya) translations for glance. # Copyright (C) 2013 ORGANIZATION # This file is distributed under the same license as the glance project. # # Translators: msgid "" msgstr "" "Project-Id-Version: Glance\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2013-08-30 08:49+0000\n" "Last-Translator: openstackjenkins \n" "Language-Team: Swahili (Kenya) " "(http://www.transifex.com/projects/p/openstack/language/sw_KE/)\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/es/0000775000175400017540000000000012323736427017300 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/es/LC_MESSAGES/0000775000175400017540000000000012323736427021065 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/es/LC_MESSAGES/glance.po0000664000175400017540000030211112323736226022651 0ustar jenkinsjenkins00000000000000# Spanish translations for PROJECT. # Copyright (C) 2012 ORGANIZATION # This file is distributed under the same license as the PROJECT project. # FIRST AUTHOR , 2012. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2012-04-26 17:40+0800\n" "Last-Translator: FULL NAME \n" "Language-Team: es \n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/eu/0000775000175400017540000000000012323736427017302 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/eu/LC_MESSAGES/0000775000175400017540000000000012323736427021067 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/eu/LC_MESSAGES/glance.po0000664000175400017540000030214512323736226022662 0ustar jenkinsjenkins00000000000000# Basque translations for glance. # Copyright (C) 2013 ORGANIZATION # This file is distributed under the same license as the glance project. # # Translators: msgid "" msgstr "" "Project-Id-Version: Glance\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2013-11-21 06:05+0000\n" "Last-Translator: openstackjenkins \n" "Language-Team: Basque " "(http://www.transifex.com/projects/p/openstack/language/eu/)\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/ml_IN/0000775000175400017540000000000012323736427017667 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/ml_IN/LC_MESSAGES/0000775000175400017540000000000012323736427021454 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/ml_IN/LC_MESSAGES/glance.po0000664000175400017540000030217612323736226023253 0ustar jenkinsjenkins00000000000000# Malayalam (India) translations for glance. # Copyright (C) 2013 ORGANIZATION # This file is distributed under the same license as the glance project. # # Translators: msgid "" msgstr "" "Project-Id-Version: Glance\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2013-11-21 06:05+0000\n" "Last-Translator: openstackjenkins \n" "Language-Team: Malayalam (India) " "(http://www.transifex.com/projects/p/openstack/language/ml_IN/)\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/ka_GE/0000775000175400017540000000000012323736427017637 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/ka_GE/LC_MESSAGES/0000775000175400017540000000000012323736427021424 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/ka_GE/LC_MESSAGES/glance.po0000664000175400017540000030217112323736226023216 0ustar jenkinsjenkins00000000000000# Georgian (Georgia) translations for glance. # Copyright (C) 2013 ORGANIZATION # This file is distributed under the same license as the glance project. # # Translators: msgid "" msgstr "" "Project-Id-Version: Glance\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2013-08-30 08:49+0000\n" "Last-Translator: openstackjenkins \n" "Language-Team: Georgian (Georgia) " "(http://www.transifex.com/projects/p/openstack/language/ka_GE/)\n" "Plural-Forms: nplurals=1; plural=0\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/zh_CN/0000775000175400017540000000000012323736427017672 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/zh_CN/LC_MESSAGES/0000775000175400017540000000000012323736427021457 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/zh_CN/LC_MESSAGES/glance.po0000664000175400017540000030211512323736226023247 0ustar jenkinsjenkins00000000000000# Chinese (China) translations for PROJECT. # Copyright (C) 2012 ORGANIZATION # This file is distributed under the same license as the PROJECT project. # FIRST AUTHOR , 2012. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2012-04-26 17:40+0800\n" "Last-Translator: FULL NAME \n" "Language-Team: zh_CN \n" "Plural-Forms: nplurals=1; plural=0\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/ar/0000775000175400017540000000000012323736427017273 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/ar/LC_MESSAGES/0000775000175400017540000000000012323736427021060 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/ar/LC_MESSAGES/glance.po0000664000175400017540000030226212323736226022653 0ustar jenkinsjenkins00000000000000# Arabic translations for glance. # Copyright (C) 2013 ORGANIZATION # This file is distributed under the same license as the glance project. # # Translators: msgid "" msgstr "" "Project-Id-Version: Glance\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2013-09-12 07:56+0000\n" "Last-Translator: Tom Fifield \n" "Language-Team: Arabic " "(http://www.transifex.com/projects/p/openstack/language/ar/)\n" "Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : " "n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/ja/0000775000175400017540000000000012323736427017263 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/ja/LC_MESSAGES/0000775000175400017540000000000012323736427021050 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/ja/LC_MESSAGES/glance.po0000664000175400017540000030210312323736226022635 0ustar jenkinsjenkins00000000000000# Japanese translations for PROJECT. # Copyright (C) 2012 ORGANIZATION # This file is distributed under the same license as the PROJECT project. # FIRST AUTHOR , 2012. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2012-04-26 17:40+0800\n" "Last-Translator: FULL NAME \n" "Language-Team: ja \n" "Plural-Forms: nplurals=1; plural=0\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/tl_PH/0000775000175400017540000000000012323736427017677 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/tl_PH/LC_MESSAGES/0000775000175400017540000000000012323736427021464 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/tl_PH/LC_MESSAGES/glance.po0000664000175400017540000030217512323736226023262 0ustar jenkinsjenkins00000000000000# Filipino (Philippines) translations for glance. # Copyright (C) 2013 ORGANIZATION # This file is distributed under the same license as the glance project. # # Translators: msgid "" msgstr "" "Project-Id-Version: Glance\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2013-09-26 22:10+0000\n" "Last-Translator: Tom Fifield \n" "Language-Team: Tagalog (Philippines) " "(http://www.transifex.com/projects/p/openstack/language/tl_PH/)\n" "Plural-Forms: nplurals=2; plural=(n > 1)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/sr/0000775000175400017540000000000012323736427017315 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/sr/LC_MESSAGES/0000775000175400017540000000000012323736427021102 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/sr/LC_MESSAGES/glance.po0000664000175400017540000030233412323736226022675 0ustar jenkinsjenkins00000000000000# Serbian translations for glance. # Copyright (C) 2014 ORGANIZATION # This file is distributed under the same license as the glance project. # # Translators: msgid "" msgstr "" "Project-Id-Version: Glance\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2014-03-25 06:03+0000\n" "Last-Translator: openstackjenkins \n" "Language-Team: Serbian " "(http://www.transifex.com/projects/p/openstack/language/sr/)\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "syslog okruženje mora biti jedno od: %s" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/hr/0000775000175400017540000000000012323736427017302 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/hr/LC_MESSAGES/0000775000175400017540000000000012323736427021067 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/hr/LC_MESSAGES/glance.po0000664000175400017540000030226412323736226022664 0ustar jenkinsjenkins00000000000000# Croatian translations for glance. # Copyright (C) 2013 ORGANIZATION # This file is distributed under the same license as the glance project. # # Translators: msgid "" msgstr "" "Project-Id-Version: Glance\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2013-08-30 08:49+0000\n" "Last-Translator: openstackjenkins \n" "Language-Team: Croatian " "(http://www.transifex.com/projects/p/openstack/language/hr/)\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/ko/0000775000175400017540000000000012323736427017302 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/ko/LC_MESSAGES/0000775000175400017540000000000012323736427021067 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/ko/LC_MESSAGES/glance.po0000664000175400017540000030210112323736226022652 0ustar jenkinsjenkins00000000000000# Korean translations for PROJECT. # Copyright (C) 2012 ORGANIZATION # This file is distributed under the same license as the PROJECT project. # FIRST AUTHOR , 2012. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2012-04-26 17:40+0800\n" "Last-Translator: FULL NAME \n" "Language-Team: ko \n" "Plural-Forms: nplurals=1; plural=0\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/sq/0000775000175400017540000000000012323736427017314 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/sq/LC_MESSAGES/0000775000175400017540000000000012323736427021101 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/sq/LC_MESSAGES/glance.po0000664000175400017540000030215112323736226022671 0ustar jenkinsjenkins00000000000000# Albanian translations for glance. # Copyright (C) 2014 ORGANIZATION # This file is distributed under the same license as the glance project. # # Translators: msgid "" msgstr "" "Project-Id-Version: Glance\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2014-03-25 06:03+0000\n" "Last-Translator: openstackjenkins \n" "Language-Team: Albanian " "(http://www.transifex.com/projects/p/openstack/language/sq/)\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/it/0000775000175400017540000000000012323736427017305 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/it/LC_MESSAGES/0000775000175400017540000000000012323736427021072 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/it/LC_MESSAGES/glance.po0000664000175400017540000030211112323736226022656 0ustar jenkinsjenkins00000000000000# Italian translations for PROJECT. # Copyright (C) 2012 ORGANIZATION # This file is distributed under the same license as the PROJECT project. # FIRST AUTHOR , 2012. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2012-04-26 17:40+0800\n" "Last-Translator: FULL NAME \n" "Language-Team: it \n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/gl/0000775000175400017540000000000012323736427017273 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/gl/LC_MESSAGES/0000775000175400017540000000000012323736427021060 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/gl/LC_MESSAGES/glance.po0000664000175400017540000030214012323736226022646 0ustar jenkinsjenkins00000000000000# Galician translations for glance. # Copyright (C) 2013 ORGANIZATION # This file is distributed under the same license as the glance project. # # Translators: msgid "" msgstr "" "Project-Id-Version: Glance\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2013-10-28 23:23+0000\n" "Last-Translator: Tom Fifield \n" "Language-Team: Galician " "(http://www.transifex.com/projects/p/openstack/language/gl/)\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/kn/0000775000175400017540000000000012323736427017301 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/kn/LC_MESSAGES/0000775000175400017540000000000012323736427021066 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/kn/LC_MESSAGES/glance.po0000664000175400017540000030212712323736226022661 0ustar jenkinsjenkins00000000000000# Kannada translations for glance. # Copyright (C) 2013 ORGANIZATION # This file is distributed under the same license as the glance project. # # Translators: msgid "" msgstr "" "Project-Id-Version: Glance\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2013-09-17 14:44+0000\n" "Last-Translator: Tom Fifield \n" "Language-Team: Kannada " "(http://www.transifex.com/projects/p/openstack/language/kn/)\n" "Plural-Forms: nplurals=1; plural=0\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/ca/0000775000175400017540000000000012323736427017254 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/ca/LC_MESSAGES/0000775000175400017540000000000012323736427021041 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/ca/LC_MESSAGES/glance.po0000664000175400017540000030214712323736226022636 0ustar jenkinsjenkins00000000000000# Catalan translations for glance. # Copyright (C) 2013 ORGANIZATION # This file is distributed under the same license as the glance project. # # Translators: msgid "" msgstr "" "Project-Id-Version: Glance\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2013-08-30 08:49+0000\n" "Last-Translator: openstackjenkins \n" "Language-Team: Catalan " "(http://www.transifex.com/projects/p/openstack/language/ca/)\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/fil/0000775000175400017540000000000012323736427017443 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/fil/LC_MESSAGES/0000775000175400017540000000000012323736427021230 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/fil/LC_MESSAGES/glance.po0000664000175400017540000030214012323736226023016 0ustar jenkinsjenkins00000000000000# Filipino translations for glance. # Copyright (C) 2013 ORGANIZATION # This file is distributed under the same license as the glance project. # # Translators: msgid "" msgstr "" "Project-Id-Version: Glance\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2013-09-26 22:10+0000\n" "Last-Translator: Tom Fifield \n" "Language-Team: Filipino " "(http://www.transifex.com/projects/p/openstack/language/fil/)\n" "Plural-Forms: nplurals=2; plural=(n > 1)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/zh_TW/0000775000175400017540000000000012323736427017724 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/zh_TW/LC_MESSAGES/0000775000175400017540000000000012323736427021511 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/zh_TW/LC_MESSAGES/glance.po0000664000175400017540000030211612323736226023302 0ustar jenkinsjenkins00000000000000# Chinese (Taiwan) translations for PROJECT. # Copyright (C) 2012 ORGANIZATION # This file is distributed under the same license as the PROJECT project. # FIRST AUTHOR , 2012. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2012-04-26 17:40+0800\n" "Last-Translator: FULL NAME \n" "Language-Team: zh_TW \n" "Plural-Forms: nplurals=1; plural=0\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/bn_IN/0000775000175400017540000000000012323736427017656 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/bn_IN/LC_MESSAGES/0000775000175400017540000000000012323736427021443 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/bn_IN/LC_MESSAGES/glance.po0000664000175400017540000030217212323736226023236 0ustar jenkinsjenkins00000000000000# Bengali (India) translations for glance. # Copyright (C) 2013 ORGANIZATION # This file is distributed under the same license as the glance project. # # Translators: msgid "" msgstr "" "Project-Id-Version: Glance\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2013-10-28 06:02+0000\n" "Last-Translator: openstackjenkins \n" "Language-Team: Bengali (India) " "(http://www.transifex.com/projects/p/openstack/language/bn_IN/)\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/tr/0000775000175400017540000000000012323736427017316 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/tr/LC_MESSAGES/0000775000175400017540000000000012323736427021103 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/tr/LC_MESSAGES/glance.po0000664000175400017540000030210212323736226022667 0ustar jenkinsjenkins00000000000000# Turkish translations for PROJECT. # Copyright (C) 2012 ORGANIZATION # This file is distributed under the same license as the PROJECT project. # FIRST AUTHOR , 2012. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2012-04-26 17:40+0800\n" "Last-Translator: FULL NAME \n" "Language-Team: tr \n" "Plural-Forms: nplurals=1; plural=0\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/el/0000775000175400017540000000000012323736427017271 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/el/LC_MESSAGES/0000775000175400017540000000000012323736427021056 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/el/LC_MESSAGES/glance.po0000664000175400017540000030214312323736226022647 0ustar jenkinsjenkins00000000000000# Greek translations for glance. # Copyright (C) 2014 ORGANIZATION # This file is distributed under the same license as the glance project. # # Translators: msgid "" msgstr "" "Project-Id-Version: Glance\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2014-03-25 06:03+0000\n" "Last-Translator: openstackjenkins \n" "Language-Team: Greek " "(http://www.transifex.com/projects/p/openstack/language/el/)\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/ro/0000775000175400017540000000000012323736427017311 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/ro/LC_MESSAGES/0000775000175400017540000000000012323736427021076 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/ro/LC_MESSAGES/glance.po0000664000175400017540000030222512323736226022670 0ustar jenkinsjenkins00000000000000# Romanian translations for glance. # Copyright (C) 2013 ORGANIZATION # This file is distributed under the same license as the glance project. # # Translators: msgid "" msgstr "" "Project-Id-Version: Glance\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2013-08-30 08:49+0000\n" "Last-Translator: openstackjenkins \n" "Language-Team: Romanian " "(http://www.transifex.com/projects/p/openstack/language/ro/)\n" "Plural-Forms: nplurals=3; " "plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1))\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/is_IS/0000775000175400017540000000000012323736427017677 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/is_IS/LC_MESSAGES/0000775000175400017540000000000012323736427021464 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/is_IS/LC_MESSAGES/glance.po0000664000175400017540000030220212323736226023251 0ustar jenkinsjenkins00000000000000# Icelandic (Iceland) translations for glance. # Copyright (C) 2014 ORGANIZATION # This file is distributed under the same license as the glance project. # # Translators: msgid "" msgstr "" "Project-Id-Version: Glance\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2014-01-28 06:02+0000\n" "Last-Translator: openstackjenkins \n" "Language-Team: Icelandic (Iceland) " "(http://www.transifex.com/projects/p/openstack/language/is_IS/)\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/hi/0000775000175400017540000000000012323736427017271 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/hi/LC_MESSAGES/0000775000175400017540000000000012323736427021056 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/hi/LC_MESSAGES/glance.po0000664000175400017540000030214312323736226022647 0ustar jenkinsjenkins00000000000000# Hindi translations for glance. # Copyright (C) 2013 ORGANIZATION # This file is distributed under the same license as the glance project. # # Translators: msgid "" msgstr "" "Project-Id-Version: Glance\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2013-08-30 08:49+0000\n" "Last-Translator: openstackjenkins \n" "Language-Team: Hindi " "(http://www.transifex.com/projects/p/openstack/language/hi/)\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/te_IN/0000775000175400017540000000000012323736427017667 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/te_IN/LC_MESSAGES/0000775000175400017540000000000012323736427021454 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/te_IN/LC_MESSAGES/glance.po0000664000175400017540000030217012323736226023245 0ustar jenkinsjenkins00000000000000# Telugu (India) translations for glance. # Copyright (C) 2014 ORGANIZATION # This file is distributed under the same license as the glance project. # # Translators: msgid "" msgstr "" "Project-Id-Version: Glance\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2014-03-25 06:03+0000\n" "Last-Translator: openstackjenkins \n" "Language-Team: Telugu (India) " "(http://www.transifex.com/projects/p/openstack/language/te_IN/)\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/ru_RU/0000775000175400017540000000000012323736427017725 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/ru_RU/LC_MESSAGES/0000775000175400017540000000000012323736427021512 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/ru_RU/LC_MESSAGES/glance.po0000664000175400017540000030231112323736226023300 0ustar jenkinsjenkins00000000000000# Russian (Russia) translations for glance. # Copyright (C) 2013 ORGANIZATION # This file is distributed under the same license as the glance project. # # Translators: msgid "" msgstr "" "Project-Id-Version: Glance\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2013-08-30 08:49+0000\n" "Last-Translator: openstackjenkins \n" "Language-Team: Russian (Russia) " "(http://www.transifex.com/projects/p/openstack/language/ru_RU/)\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/glance.pot0000664000175400017540000030210512323736226020644 0ustar jenkinsjenkins00000000000000# Translations template for glance. # Copyright (C) 2014 ORGANIZATION # This file is distributed under the same license as the glance project. # FIRST AUTHOR , 2014. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: glance jenkins.glance.propose.translation.update.360\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\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 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/en_AU/0000775000175400017540000000000012323736427017660 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/en_AU/LC_MESSAGES/0000775000175400017540000000000012323736427021445 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/en_AU/LC_MESSAGES/glance.po0000664000175400017540000030213012323736226023232 0ustar jenkinsjenkins00000000000000# English (Australia) translations for PROJECT. # Copyright (C) 2012 ORGANIZATION # This file is distributed under the same license as the PROJECT project. # FIRST AUTHOR , 2012. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2012-04-26 17:39+0800\n" "Last-Translator: FULL NAME \n" "Language-Team: en_AU \n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/mr_IN/0000775000175400017540000000000012323736427017675 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/mr_IN/LC_MESSAGES/0000775000175400017540000000000012323736427021462 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/mr_IN/LC_MESSAGES/glance.po0000664000175400017540000030217212323736226023255 0ustar jenkinsjenkins00000000000000# Marathi (India) translations for glance. # Copyright (C) 2013 ORGANIZATION # This file is distributed under the same license as the glance project. # # Translators: msgid "" msgstr "" "Project-Id-Version: Glance\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2013-10-28 06:02+0000\n" "Last-Translator: openstackjenkins \n" "Language-Team: Marathi (India) " "(http://www.transifex.com/projects/p/openstack/language/mr_IN/)\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/fr/0000775000175400017540000000000012323736427017300 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/fr/LC_MESSAGES/0000775000175400017540000000000012323736427021065 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/fr/LC_MESSAGES/glance.po0000664000175400017540000030210712323736226022656 0ustar jenkinsjenkins00000000000000# French translations for PROJECT. # Copyright (C) 2012 ORGANIZATION # This file is distributed under the same license as the PROJECT project. # FIRST AUTHOR , 2012. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2012-04-26 17:40+0800\n" "Last-Translator: FULL NAME \n" "Language-Team: fr \n" "Plural-Forms: nplurals=2; plural=(n > 1)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/fi_FI/0000775000175400017540000000000012323736427017645 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/fi_FI/LC_MESSAGES/0000775000175400017540000000000012323736427021432 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/fi_FI/LC_MESSAGES/glance.po0000664000175400017540000030217612323736226023231 0ustar jenkinsjenkins00000000000000# Finnish (Finland) translations for glance. # Copyright (C) 2013 ORGANIZATION # This file is distributed under the same license as the glance project. # # Translators: msgid "" msgstr "" "Project-Id-Version: Glance\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2013-08-30 08:49+0000\n" "Last-Translator: openstackjenkins \n" "Language-Team: Finnish (Finland) " "(http://www.transifex.com/projects/p/openstack/language/fi_FI/)\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/nb/0000775000175400017540000000000012323736427017270 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/nb/LC_MESSAGES/0000775000175400017540000000000012323736427021055 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/nb/LC_MESSAGES/glance.po0000664000175400017540000030224612323736226022652 0ustar jenkinsjenkins00000000000000# Norwegian Bokmål translations for glance. # Copyright (C) 2013 ORGANIZATION # This file is distributed under the same license as the glance project. # # Translators: msgid "" msgstr "" "Project-Id-Version: Glance\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2013-08-30 08:49+0000\n" "Last-Translator: openstackjenkins \n" "Language-Team: Norwegian Bokmål " "(http://www.transifex.com/projects/p/openstack/language/nb/)\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "Resultat var %s" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "%r feilet. Prøver på nytt." #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/it_IT/0000775000175400017540000000000012323736427017701 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/it_IT/LC_MESSAGES/0000775000175400017540000000000012323736427021466 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/it_IT/LC_MESSAGES/glance.po0000664000175400017540000030217212323736226023261 0ustar jenkinsjenkins00000000000000# Italian (Italy) translations for glance. # Copyright (C) 2013 ORGANIZATION # This file is distributed under the same license as the glance project. # # Translators: msgid "" msgstr "" "Project-Id-Version: Glance\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2013-08-30 08:49+0000\n" "Last-Translator: openstackjenkins \n" "Language-Team: Italian (Italy) " "(http://www.transifex.com/projects/p/openstack/language/it_IT/)\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/bs/0000775000175400017540000000000012323736427017275 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/bs/LC_MESSAGES/0000775000175400017540000000000012323736427021062 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/bs/LC_MESSAGES/glance.po0000664000175400017540000030211112323736226022646 0ustar jenkinsjenkins00000000000000# Bosnian translations for PROJECT. # Copyright (C) 2012 ORGANIZATION # This file is distributed under the same license as the PROJECT project. # FIRST AUTHOR , 2012. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2012-04-26 17:38+0800\n" "Last-Translator: FULL NAME \n" "Language-Team: bs \n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/ru/0000775000175400017540000000000012323736427017317 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/ru/LC_MESSAGES/0000775000175400017540000000000012323736427021104 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/ru/LC_MESSAGES/glance.po0000664000175400017540000030222612323736226022677 0ustar jenkinsjenkins00000000000000# Russian translations for PROJECT. # Copyright (C) 2012 ORGANIZATION # This file is distributed under the same license as the PROJECT project. # FIRST AUTHOR , 2012. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2012-04-26 17:40+0800\n" "Last-Translator: FULL NAME \n" "Language-Team: ru \n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/km/0000775000175400017540000000000012323736427017300 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/km/LC_MESSAGES/0000775000175400017540000000000012323736427021065 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/km/LC_MESSAGES/glance.po0000664000175400017540000030213412323736226022656 0ustar jenkinsjenkins00000000000000# Khmer translations for glance. # Copyright (C) 2013 ORGANIZATION # This file is distributed under the same license as the glance project. # # Translators: msgid "" msgstr "" "Project-Id-Version: Glance\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2013-11-21 06:05+0000\n" "Last-Translator: openstackjenkins \n" "Language-Team: Khmer " "(http://www.transifex.com/projects/p/openstack/language/km/)\n" "Plural-Forms: nplurals=1; plural=0\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/en_GB/0000775000175400017540000000000012323736427017643 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/en_GB/LC_MESSAGES/0000775000175400017540000000000012323736427021430 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/en_GB/LC_MESSAGES/glance.po0000664000175400017540000030213512323736226023222 0ustar jenkinsjenkins00000000000000# English (United Kingdom) translations for PROJECT. # Copyright (C) 2012 ORGANIZATION # This file is distributed under the same license as the PROJECT project. # FIRST AUTHOR , 2012. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2012-04-26 17:39+0800\n" "Last-Translator: FULL NAME \n" "Language-Team: en_GB \n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/bg_BG/0000775000175400017540000000000012323736427017631 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/bg_BG/LC_MESSAGES/0000775000175400017540000000000012323736427021416 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/bg_BG/LC_MESSAGES/glance.po0000664000175400017540000030220412323736226023205 0ustar jenkinsjenkins00000000000000# Bulgarian (Bulgaria) translations for glance. # Copyright (C) 2013 ORGANIZATION # This file is distributed under the same license as the glance project. # # Translators: msgid "" msgstr "" "Project-Id-Version: Glance\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2013-08-30 08:49+0000\n" "Last-Translator: openstackjenkins \n" "Language-Team: Bulgarian (Bulgaria) " "(http://www.transifex.com/projects/p/openstack/language/bg_BG/)\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/ta/0000775000175400017540000000000012323736427017275 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/ta/LC_MESSAGES/0000775000175400017540000000000012323736427021062 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/ta/LC_MESSAGES/glance.po0000664000175400017540000030214312323736226022653 0ustar jenkinsjenkins00000000000000# Tamil translations for glance. # Copyright (C) 2014 ORGANIZATION # This file is distributed under the same license as the glance project. # # Translators: msgid "" msgstr "" "Project-Id-Version: Glance\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2014-03-25 06:03+0000\n" "Last-Translator: openstackjenkins \n" "Language-Team: Tamil " "(http://www.transifex.com/projects/p/openstack/language/ta/)\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/ko_KR/0000775000175400017540000000000012323736427017676 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/ko_KR/LC_MESSAGES/0000775000175400017540000000000012323736427021463 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/ko_KR/LC_MESSAGES/glance.po0000664000175400017540000030540712323736226023262 0ustar jenkinsjenkins00000000000000# Korean (South Korea) translations for glance. # Copyright (C) 2013 ORGANIZATION # This file is distributed under the same license as the glance project. # # Translators: msgid "" msgstr "" "Project-Id-Version: Glance\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2013-08-30 08:49+0000\n" "Last-Translator: openstackjenkins \n" "Language-Team: Korean (Korea) " "(http://www.transifex.com/projects/p/openstack/language/ko_KR/)\n" "Plural-Forms: nplurals=1; plural=0\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "올바르지 ì•Šì€ ì„œë¹„ìŠ¤ 카탈로그 json입니다. " #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "limit 매개변수는 정수여야 함" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "limit 매개변수가 양수여야 함" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "제공ë˜ëŠ” ì •ë ¬ 키가 올바르지 않습니다. " #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "올바르지 ì•Šì€ ë°±ì—”ë“œ: %s" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 msgid "" "When running server in SSL mode, you must specify both a cert_file and " "key_file option value in your configuration file" msgstr "서버를 SSL 모드ì—서 실행할 때 구성 파ì¼ì— cert_file ë° key_file 옵션 ê°’ì„ ëª¨ë‘ ì§€ì •í•´ì•¼ 함" #: glance/common/wsgi.py:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "%d ìž‘ì—…ìž ì‹œìž‘ 중" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "IDê°€ sort_keysì— ì—†ìŠµë‹ˆë‹¤. sort_keysê°€ 고유합니까?" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "알 수 없는 ì •ë ¬ 방향입니다. 'desc' ë˜ëŠ” 'asc'여야 함" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "ì›ëž˜ 예외가 ì‚­ì œë¨: %s" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "ë” ì´ìƒ 사용ë˜ì§€ 않ìŒ: %s" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "syslog ê¸°ëŠ¥ì´ ë‹¤ìŒ ì¤‘ 하나여야 함: %s" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "ë” ì´ìƒ 사용ë˜ì§€ 않는 êµ¬ì„±ì— ëŒ€í•œ 심ê°í•œ 호출: %(msg)s" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "íƒœìŠ¤í¬ ì‹¤í–‰ì´ %sì´ˆì˜ ê°„ê²©ì„ ì§€ì†í•¨" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "ê³ ì • 기간 루프 호출ì—서" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "ë™ì  루프 호출ì—서" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "%(rule)s ê·œì¹™ì„ ì´í•´í•˜ì§€ 못했ìŒ" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "%s ìœ í˜•ì˜ ì¼ì¹˜ì— 대한 핸들러가 ì—†ìŒ" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "%(rule)r ê·œì¹™ì„ ì´í•´í•˜ì§€ 못했ìŒ" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "utils.executeì— ëŒ€í•´ 알 수 없는 키워드 ì¸ìˆ˜ë¥¼ 가져옴: %r" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "cmd(하위 프로세스) 실행 중: %s" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "결과는 %s입니다." #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "%r 실패. ìž¬ì‹œë„ ì¤‘ìž…ë‹ˆë‹¤. " #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "cmd(SSH) 실행 중: %s" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "í™˜ê²½ì´ SSH를 통해 ì§€ì›ë˜ì§€ 않ìŒ" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "process_inputì´ SSH를 통해 ì§€ì›ë˜ì§€ 않ìŒ" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "CONFì˜ ì „ì²´ 세트:" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "%s 발견, 종료 중" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "ìƒìœ„ 프로세스가 예기치 않게 정지했습니다. 종료 중" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "í¬í¬ê°€ 너무 빠름. ì •ì§€ 중" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "처리ë˜ì§€ ì•Šì€ ì˜ˆì™¸" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "%d 하위를 시작했ìŒ" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "%(pid)d 하위가 %(sig)d ì‹ í˜¸ì— ì˜í•´ ê°•ì œ 종료ë¨" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "%(pid)s 하위가 %(code)d ìƒíƒœì™€ 함께 종료했ìŒ" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "pid %dì´(ê°€) 하위 목ë¡ì— ì—†ìŒ" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "%s 발견, 하위 중지 중" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "%d 하위ì—서 종료하기를 대기 중임" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "Cinderclient ì—°ê²°ì´ URLì„ ì‚¬ìš©í•˜ì—¬ 작성ë¨: %s" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/ne/0000775000175400017540000000000012323736427017273 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/ne/LC_MESSAGES/0000775000175400017540000000000012323736427021060 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/ne/LC_MESSAGES/glance.po0000664000175400017540000030214012323736226022646 0ustar jenkinsjenkins00000000000000# Nepali translations for glance. # Copyright (C) 2013 ORGANIZATION # This file is distributed under the same license as the glance project. # # Translators: msgid "" msgstr "" "Project-Id-Version: Glance\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2013-08-30 22:38+0000\n" "Last-Translator: daisy.ycguo \n" "Language-Team: Nepali " "(http://www.transifex.com/projects/p/openstack/language/ne/)\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/pa_IN/0000775000175400017540000000000012323736427017657 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/pa_IN/LC_MESSAGES/0000775000175400017540000000000012323736427021444 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/pa_IN/LC_MESSAGES/glance.po0000664000175400017540000030221612323736226023236 0ustar jenkinsjenkins00000000000000# Punjabi (Gurmukhi, India) translations for glance. # Copyright (C) 2014 ORGANIZATION # This file is distributed under the same license as the glance project. # # Translators: msgid "" msgstr "" "Project-Id-Version: Glance\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2014-01-28 06:02+0000\n" "Last-Translator: openstackjenkins \n" "Language-Team: Panjabi (Punjabi) (India) " "(http://www.transifex.com/projects/p/openstack/language/pa_IN/)\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/he_IL/0000775000175400017540000000000012323736427017651 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/he_IL/LC_MESSAGES/0000775000175400017540000000000012323736427021436 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/he_IL/LC_MESSAGES/glance.po0000664000175400017540000030217212323736226023231 0ustar jenkinsjenkins00000000000000# Hebrew (Israel) translations for glance. # Copyright (C) 2014 ORGANIZATION # This file is distributed under the same license as the glance project. # # Translators: msgid "" msgstr "" "Project-Id-Version: Glance\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2014-01-28 06:02+0000\n" "Last-Translator: openstackjenkins \n" "Language-Team: Hebrew (Israel) " "(http://www.transifex.com/projects/p/openstack/language/he_IL/)\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/fa/0000775000175400017540000000000012323736427017257 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/fa/LC_MESSAGES/0000775000175400017540000000000012323736427021044 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/fa/LC_MESSAGES/glance.po0000664000175400017540000030214012323736226022632 0ustar jenkinsjenkins00000000000000# Persian translations for glance. # Copyright (C) 2013 ORGANIZATION # This file is distributed under the same license as the glance project. # # Translators: msgid "" msgstr "" "Project-Id-Version: Glance\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2013-11-21 06:05+0000\n" "Last-Translator: openstackjenkins \n" "Language-Team: Persian " "(http://www.transifex.com/projects/p/openstack/language/fa/)\n" "Plural-Forms: nplurals=1; plural=0\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/uk/0000775000175400017540000000000012323736427017310 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/uk/LC_MESSAGES/0000775000175400017540000000000012323736427021075 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/uk/LC_MESSAGES/glance.po0000664000175400017540000030223012323736226022663 0ustar jenkinsjenkins00000000000000# Ukrainian translations for PROJECT. # Copyright (C) 2012 ORGANIZATION # This file is distributed under the same license as the PROJECT project. # FIRST AUTHOR , 2012. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2012-04-26 17:40+0800\n" "Last-Translator: FULL NAME \n" "Language-Team: uk \n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/pt_BR/0000775000175400017540000000000012323736427017677 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/pt_BR/LC_MESSAGES/0000775000175400017540000000000012323736427021464 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/pt_BR/LC_MESSAGES/glance.po0000664000175400017540000030212712323736226023257 0ustar jenkinsjenkins00000000000000# Portuguese (Brazil) translations for PROJECT. # Copyright (C) 2012 ORGANIZATION # This file is distributed under the same license as the PROJECT project. # FIRST AUTHOR , 2012. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2012-04-26 17:40+0800\n" "Last-Translator: FULL NAME \n" "Language-Team: pt_BR \n" "Plural-Forms: nplurals=2; plural=(n > 1)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/sk/0000775000175400017540000000000012323736427017306 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/sk/LC_MESSAGES/0000775000175400017540000000000012323736427021073 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/sk/LC_MESSAGES/glance.po0000664000175400017540000030220012323736226022656 0ustar jenkinsjenkins00000000000000# Slovak translations for glance. # Copyright (C) 2013 ORGANIZATION # This file is distributed under the same license as the glance project. # # Translators: msgid "" msgstr "" "Project-Id-Version: Glance\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2013-08-30 08:49+0000\n" "Last-Translator: openstackjenkins \n" "Language-Team: Slovak " "(http://www.transifex.com/projects/p/openstack/language/sk/)\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/de/0000775000175400017540000000000012323736427017261 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/de/LC_MESSAGES/0000775000175400017540000000000012323736427021046 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/de/LC_MESSAGES/glance.po0000664000175400017540000030211012323736226022631 0ustar jenkinsjenkins00000000000000# German translations for PROJECT. # Copyright (C) 2012 ORGANIZATION # This file is distributed under the same license as the PROJECT project. # FIRST AUTHOR , 2012. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2012-04-26 17:39+0800\n" "Last-Translator: FULL NAME \n" "Language-Team: de \n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/locale/vi_VN/0000775000175400017540000000000012323736427017712 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/vi_VN/LC_MESSAGES/0000775000175400017540000000000012323736427021477 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/locale/vi_VN/LC_MESSAGES/glance.po0000664000175400017540000030217612323736226023276 0ustar jenkinsjenkins00000000000000# Vietnamese (Vietnam) translations for glance. # Copyright (C) 2013 ORGANIZATION # This file is distributed under the same license as the glance project. # # Translators: msgid "" msgstr "" "Project-Id-Version: Glance\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2014-03-26 06:02+0000\n" "PO-Revision-Date: 2013-08-30 08:49+0000\n" "Last-Translator: openstackjenkins \n" "Language-Team: Vietnamese (Viet Nam) " "(http://www.transifex.com/projects/p/openstack/language/vi_VN/)\n" "Plural-Forms: nplurals=1; plural=0\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: glance/notifier.py:28 msgid "" "Notifications can be sent when images are create, updated or deleted. " "There are three methods of sending notifications, logging (via the " "log_file directive), rabbit (via a rabbitmq queue), qpid (via a Qpid " "message queue), or noop (no notifications sent, the default). " "(DEPRECATED)" msgstr "" #: glance/notifier.py:68 msgid "notifier_strategy was deprecated in favor of `notification_driver`" msgstr "" #: glance/notifier.py:229 glance/api/common.py:82 #, python-format msgid "An error occurred during image.send notification: %(err)s" msgstr "" #: glance/notifier.py:239 glance/api/v1/upload_utils.py:184 #: glance/api/v2/image_data.py:107 #, python-format msgid "Image storage media is full: %s" msgstr "" #: glance/notifier.py:243 glance/api/v1/upload_utils.py:193 #: glance/api/v2/image_data.py:128 #, python-format msgid "Insufficient permissions on image storage media: %s" msgstr "" #: glance/notifier.py:248 #, python-format msgid "Cannot save data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:254 #, python-format msgid "Unable to upload duplicate image data for image%(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:261 #, python-format msgid "Not allowed to upload image data for image %(image_id)s: %(error)s" msgstr "" #: glance/notifier.py:267 #, python-format msgid "" "Image %(image_id)s could not be found after upload. The image may have " "been deleted during the upload: %(error)s" msgstr "" #: glance/notifier.py:274 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to HTTP error: " "%(error)s" msgstr "" #: glance/notifier.py:281 #, python-format msgid "" "Failed to upload image data for image %(image_id)s due to internal error:" " %(error)s" msgstr "" #: glance/schema.py:58 #, python-format msgid "custom properties (%(props)s) conflict with base properties" msgstr "" #: glance/scrubber.py:37 glance/store/__init__.py:48 msgid "" "Directory that the scrubber will use to track information about what to " "delete. Make sure this is set in glance-api.conf and glance-" "scrubber.conf." msgstr "" #: glance/scrubber.py:42 glance/store/__init__.py:58 msgid "The amount of time in seconds to delay before performing a delete." msgstr "" #: glance/scrubber.py:45 msgid "" "A boolean that determines if the scrubber should clean up the files it " "uses for taking data. Only one server in your deployment should be " "designated the cleanup host." msgstr "" #: glance/scrubber.py:50 msgid "" "Items must have a modified time that is older than this value in order to" " be candidates for cleanup." msgstr "" #: glance/scrubber.py:134 #, python-format msgid "%s file can not be read." msgstr "" #: glance/scrubber.py:158 #, python-format msgid "%s file can not be wrote." msgstr "" #: glance/scrubber.py:183 glance/api/v1/images.py:1022 #, python-format msgid "Failed to find image to delete: %(e)s" msgstr "" #: glance/scrubber.py:215 #, python-format msgid "%s directory does not exist." msgstr "" #: glance/scrubber.py:362 #, python-format msgid "Starting Daemon: wakeup_time=%(wakeup_time)s threads=%(threads)s" msgstr "" #: glance/scrubber.py:376 msgid "Daemon Shutdown on KeyboardInterrupt" msgstr "" #: glance/scrubber.py:380 msgid "Running application" msgstr "" #: glance/scrubber.py:383 #, python-format msgid "Next run scheduled in %s seconds" msgstr "" #: glance/scrubber.py:388 #, python-format msgid "Initializing scrubber with configuration: %s" msgstr "" #: glance/scrubber.py:412 #, python-format msgid "Can not %s scrub jobs from queue." msgstr "" #: glance/scrubber.py:436 #, python-format msgid "Scrubbing image %(id)s from %(count)d locations." msgstr "" #: glance/scrubber.py:451 #, python-format msgid "Deleting URI from image %(image_id)s." msgstr "" #: glance/scrubber.py:464 #, python-format msgid "Failed to delete URI from image %(image_id)s" msgstr "" #: glance/scrubber.py:476 #, python-format msgid "%s file is not exists." msgstr "" #: glance/scrubber.py:481 #, python-format msgid "%s file contains conflicting cleanup timestamp." msgstr "" #: glance/scrubber.py:500 #, python-format msgid "%s file can not be created." msgstr "" #: glance/scrubber.py:514 #, python-format msgid "Getting images deleted before %s" msgstr "" #: glance/api/authorization.py:118 glance/api/authorization.py:129 #, python-format msgid "You cannot get image member for %s" msgstr "" #: glance/api/authorization.py:137 #, python-format msgid "You cannot delete image member for %s" msgstr "" #: glance/api/authorization.py:146 #, python-format msgid "You cannot add image member for %s" msgstr "" #: glance/api/authorization.py:155 #, python-format msgid "You cannot update image member %s" msgstr "" #: glance/api/authorization.py:174 #, python-format msgid "You are not permitted to create images owned by '%s'." msgstr "" #: glance/api/authorization.py:192 msgid "You are not permitted to create image members for the image." msgstr "" #: glance/api/authorization.py:197 glance/api/authorization.py:380 msgid "Public images do not have members." msgstr "" #: glance/api/authorization.py:213 #, python-format msgid "You are not permitted to modify '%(attr)s' on this %(resource)s." msgstr "" #: glance/api/authorization.py:223 msgid "You are not permitted to modify locations for this image." msgstr "" #: glance/api/authorization.py:247 #, python-format msgid "You are not permitted to modify '%s' on this image." msgstr "" #: glance/api/authorization.py:251 msgid "You are not permitted to modify this image." msgstr "" #: glance/api/authorization.py:264 msgid "You are not permitted to modify tags on this image." msgstr "" #: glance/api/authorization.py:305 msgid "You are not permitted to delete this image." msgstr "" #: glance/api/authorization.py:316 msgid "You are not permitted to upload data for this image." msgstr "" #: glance/api/authorization.py:350 glance/api/authorization.py:354 #: glance/api/authorization.py:358 msgid "You are not permitted to set status on this task." msgstr "" #: glance/api/authorization.py:420 #, python-format msgid "You are not permitted to create this task with owner as: %s" msgstr "" #: glance/api/common.py:44 #, python-format msgid "" "An error occurred reading from backend storage for image %(image_id)s: " "%(err)s" msgstr "" #: glance/api/common.py:51 #, python-format msgid "" "Backend storage for image %(image_id)s disconnected after writing only " "%(bytes_written)d bytes" msgstr "" #: glance/api/common.py:56 #, python-format msgid "Corrupt image download for image %(image_id)s" msgstr "" #: glance/api/common.py:134 #, python-format msgid "" "User %(user)s attempted to upload an image of unknown size that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/common.py:143 #, python-format msgid "" "User %(user)s attempted to upload an image of size %(size)d that will " "exceeed the quota. %(remaining)d bytes remaining." msgstr "" #: glance/api/policy.py:34 msgid "The location of the policy file." msgstr "" #: glance/api/policy.py:36 msgid "The default policy to use." msgstr "" #: glance/api/policy.py:83 #, python-format msgid "Loaded %(rule_type)spolicy rules: %(text_rules)s" msgstr "" #: glance/api/policy.py:96 msgid "Unable to find policy file" msgstr "" #: glance/api/policy.py:106 #, python-format msgid "Loading policy from %s" msgstr "" #: glance/api/policy.py:220 glance/quota/__init__.py:343 #: glance/store/__init__.py:662 #, python-format msgid "Invalid locations: %s" msgstr "" #: glance/api/middleware/cache.py:57 msgid "Initialized image cache middleware" msgstr "" #: glance/api/middleware/cache.py:125 #, python-format msgid "Cache hit for image '%s'" msgstr "" #: glance/api/middleware/cache.py:132 #, 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:230 #, python-format msgid "could not find %s" msgstr "" #: glance/api/middleware/cache.py:238 #, python-format msgid "Removing image %s from cache" msgstr "" #: glance/api/middleware/cache.py:250 msgid "Checksum header is missing." msgstr "" #: glance/api/middleware/cache_manage.py:72 msgid "Initialized image cache management middleware" msgstr "" #: glance/api/middleware/context.py:28 msgid "" "When true, this option sets the owner of an image to be the tenant. " "Otherwise, the owner of the image will be the authenticated user issuing" " the request." msgstr "" #: glance/api/middleware/context.py:33 msgid "Role used to identify an authenticated user as administrator." msgstr "" #: glance/api/middleware/context.py:36 msgid "" "Allow unauthenticated users to access the API with read-only privileges. " "This only applies when using ContextMiddleware." msgstr "" #: glance/api/middleware/context.py:52 msgid "Unable to retrieve request id from context" msgstr "" #: glance/api/middleware/context.py:109 msgid "Invalid service catalog json." msgstr "" #: glance/api/middleware/gzip.py:33 msgid "Initialized gzip middleware" msgstr "" #: glance/api/middleware/version_negotiation.py:41 #, python-format msgid "Determining version of request: %(method)s %(path)s Accept: %(accept)s" msgstr "" #: glance/api/middleware/version_negotiation.py:53 msgid "Using media-type versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:57 msgid "Using url versioning" msgstr "" #: glance/api/middleware/version_negotiation.py:64 msgid "Unknown version. Returning version choices." msgstr "" #: glance/api/middleware/version_negotiation.py:69 #, python-format msgid "Matched version: v%d" msgstr "" #: glance/api/v1/controller.py:41 glance/api/v1/members.py:76 #, python-format msgid "Image with identifier %s not found" msgstr "" #: glance/api/v1/controller.py:46 msgid "Forbidden image access" msgstr "" #: glance/api/v1/controller.py:59 #, python-format msgid "Image %s is not active" msgstr "" #: glance/api/v1/controller.py:81 #, python-format msgid "Store for image_id not found: %s" msgstr "" #: glance/api/v1/images.py:73 #, python-format msgid "Invalid disk format '%s' for image." msgstr "" #: glance/api/v1/images.py:78 #, python-format msgid "Invalid container format '%s' for image." msgstr "" #: glance/api/v1/images.py:83 #, python-format msgid "Image name too long: %d" msgstr "" #: glance/api/v1/images.py:94 msgid "" "Invalid mix of disk and container formats. When setting a disk or " "container format to one of 'aki', 'ari', or 'ami', the container and disk" " formats must match." msgstr "" #: glance/api/v1/images.py:172 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(num)s, Maximum: %(quota)s" msgstr "" #: glance/api/v1/images.py:194 glance/api/v1/images.py:238 #: glance/api/v1/images.py:272 #, python-format msgid "Property '%s' is protected" msgstr "" #: glance/api/v1/images.py:380 #, python-format msgid "Bad value passed to filter %(filter)s got %(val)s" msgstr "" #: glance/api/v1/images.py:420 #, python-format msgid "External sourcing not supported for store %s" msgstr "" #: glance/api/v1/images.py:493 #, python-format msgid "Required store %s is invalid" msgstr "" #: glance/api/v1/images.py:505 glance/api/v1/images.py:877 #, python-format msgid "Invalid location %s" msgstr "" #: glance/api/v1/images.py:528 #, python-format msgid "An image with identifier %s already exists" msgstr "" #: glance/api/v1/images.py:535 #, python-format msgid "Failed to reserve image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:542 msgid "Forbidden to reserve image." msgstr "" #: glance/api/v1/images.py:569 #, python-format msgid "Copy from external source failed: %s" msgstr "" #: glance/api/v1/images.py:578 msgid "Content-Type must be application/octet-stream" msgstr "" #: glance/api/v1/images.py:589 #, python-format msgid "Setting image %s to status 'saving'" msgstr "" #: glance/api/v1/images.py:593 #, python-format msgid "Uploading image data for image %(image_id)s to %(scheme)s store" msgstr "" #: glance/api/v1/images.py:636 #, python-format msgid "" "duplicate operation - deleting image data for %(id)s " "(location:%(location)s)" msgstr "" #: glance/api/v1/images.py:644 #, python-format msgid "Failed to activate image. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:683 msgid "It's invalid to provide multiple image sources." msgstr "" #: glance/api/v1/images.py:694 msgid "Triggering asynchronous copy from external source" msgstr "" #: glance/api/v1/images.py:709 #, python-format msgid "" "Provided image size must match the stored image size. (provided size: " "%(ps)d, stored size: %(ss)d)" msgstr "" #: glance/api/v1/images.py:831 msgid "Forbidden to update deleted image." msgstr "" #: glance/api/v1/images.py:842 #, python-format msgid "Forbidden to modify '%s' of active image." msgstr "" #: glance/api/v1/images.py:860 msgid "Cannot upload to an unqueued image" msgstr "" #: glance/api/v1/images.py:884 msgid "Attempted to update Location field for an image not in queued status." msgstr "" #: glance/api/v1/images.py:924 glance/registry/api/v1/images.py:461 #, python-format msgid "Failed to update image metadata. Got error: %(e)s" msgstr "" #: glance/api/v1/images.py:931 #, python-format msgid "Failed to find image to update: %(e)s" msgstr "" #: glance/api/v1/images.py:938 #, python-format msgid "Forbidden to update image: %(e)s" msgstr "" #: glance/api/v1/images.py:977 msgid "Image is protected" msgstr "" #: glance/api/v1/images.py:984 #, python-format msgid "Forbidden to delete a %s image." msgstr "" #: glance/api/v1/images.py:989 #, python-format msgid "Image %s not found." msgstr "" #: glance/api/v1/images.py:1029 #, python-format msgid "Forbidden to delete image: %(e)s" msgstr "" #: glance/api/v1/images.py:1052 glance/store/__init__.py:231 #, python-format msgid "Store for scheme %s not found" msgstr "" #: glance/api/v1/images.py:1091 glance/api/v1/upload_utils.py:202 #, python-format msgid "Denying attempt to upload image larger than %d bytes." msgstr "" #: glance/api/v1/members.py:41 glance/registry/api/v1/members.py:32 msgid "No authenticated user" msgstr "" #: glance/api/v1/members.py:53 #, python-format msgid "Image with identifier %s has been deleted." msgstr "" #: glance/api/v1/members.py:80 msgid "Unauthorized image access" msgstr "" #: glance/api/v1/members.py:117 glance/common/exception.py:287 #, python-format msgid "" "The limit has been exceeded on the number of allowed image members for " "this image. Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/api/v1/upload_utils.py:72 #, python-format msgid "Unable to kill image %(id)s: " msgstr "" #: glance/api/v1/upload_utils.py:107 #, python-format msgid "Cleaning up %s after exceeding the quota" msgstr "" #: glance/api/v1/upload_utils.py:115 #, python-format msgid "" "Supplied %(attr)s (%(supplied)s) and %(attr)s generated from uploaded " "image (%(actual)s) did not match. Setting image status to 'killed'." msgstr "" #: glance/api/v1/upload_utils.py:135 #, python-format msgid "" "Updating image %(image_id)s data. Checksum set to %(checksum)s, size set " "to %(size)d" msgstr "" #: glance/api/v1/upload_utils.py:148 #, python-format msgid "" "Image %s could not be found after upload. The image may have been deleted" " during the upload." msgstr "" #: glance/api/v1/upload_utils.py:164 #, python-format msgid "Attempt to upload duplicate image: %s" msgstr "" #: glance/api/v1/upload_utils.py:175 #, python-format msgid "Forbidden upload attempt: %s" msgstr "" #: glance/api/v1/upload_utils.py:212 glance/api/v2/images.py:132 #, python-format msgid "Denying attempt to upload image because it exceeds the .quota: %s" msgstr "" #: glance/api/v1/upload_utils.py:226 #, python-format msgid "Received HTTP error while uploading image %s" msgstr "" #: glance/api/v1/upload_utils.py:233 msgid "Client disconnected before sending all data to backend" msgstr "" #: glance/api/v1/upload_utils.py:241 #, python-format msgid "Failed to upload image %s" msgstr "" #: glance/api/v2/image_data.py:56 #, python-format msgid "Unable to restore image %(image_id)s: %(e)s" msgstr "" #: glance/api/v2/image_data.py:71 #, python-format msgid "" "Image %(id)s could not be found after upload.The image may have been " "deleted during the upload: %(error)s Cleaning up the chunks uploaded" msgstr "" #: glance/api/v2/image_data.py:98 #, python-format msgid "Not allowed to upload image data for image %s" msgstr "" #: glance/api/v2/image_data.py:114 #, python-format msgid "Image exceeds the storage quota: %s" msgstr "" #: glance/api/v2/image_data.py:121 #, python-format msgid "The incoming image is too large: %s" msgstr "" #: glance/api/v2/image_data.py:135 msgid "Failed to upload image data due to HTTP error" msgstr "" #: glance/api/v2/image_data.py:140 msgid "Failed to upload image data due to internal error" msgstr "" #: glance/api/v2/image_members.py:189 glance/api/v2/images.py:287 msgid "Body expected in request." msgstr "" #: glance/api/v2/image_members.py:200 msgid "Member to be added not specified" msgstr "" #: glance/api/v2/image_members.py:203 msgid "Member can't be empty" msgstr "" #: glance/api/v2/image_members.py:212 msgid "Status not specified" msgstr "" #: glance/api/v2/image_members.py:267 msgid "An identifier for the image member (tenantId)" msgstr "" #: glance/api/v2/image_members.py:271 glance/api/v2/images.py:644 msgid "An identifier for the image" msgstr "" #: glance/api/v2/image_members.py:277 msgid "Date and time of image member creation" msgstr "" #: glance/api/v2/image_members.py:284 msgid "Date and time of last modification of image member" msgstr "" #: glance/api/v2/image_members.py:289 msgid "The status of this image member" msgstr "" #: glance/api/v2/images.py:156 glance/api/v2/images.py:184 #, python-format msgid "Property %s does not exist." msgstr "" #: glance/api/v2/images.py:168 #, python-format msgid "Property %s already present." msgstr "" #: glance/api/v2/images.py:179 #, python-format msgid "Property %s may not be removed." msgstr "" #: glance/api/v2/images.py:197 #, python-format msgid "Failed to find image %(image_id)s to delete" msgstr "" #: glance/api/v2/images.py:216 msgid "Cannot replace locations from a non-empty list to a non-empty list." msgstr "" #: glance/api/v2/images.py:239 msgid "Invalid position for adding a location." msgstr "" #: glance/api/v2/images.py:254 msgid "Invalid position for removing a location." msgstr "" #: glance/api/v2/images.py:295 glance/api/v2/images.py:394 #, python-format msgid "Attribute '%s' is read-only." msgstr "" #: glance/api/v2/images.py:319 glance/api/v2/images.py:341 #, python-format msgid "Unable to find '%s' in JSON Schema change" msgstr "" #: glance/api/v2/images.py:327 msgid "" "Operation objects must contain only one member named \"add\", \"remove\"," " or \"replace\"." msgstr "" #: glance/api/v2/images.py:332 msgid "" "Operation objects must contain exactly one member named \"add\", " "\"remove\", or \"replace\"." msgstr "" #: glance/api/v2/images.py:369 #, python-format msgid "Pointer `%s` does not start with \"/\"." msgstr "" #: glance/api/v2/images.py:372 #, python-format msgid "Pointer `%s` contains adjacent \"/\"." msgstr "" #: glance/api/v2/images.py:375 #, python-format msgid "Pointer `%s` end with \"/\"." msgstr "" #: glance/api/v2/images.py:378 #, python-format msgid "Pointer `%s` does not contains valid token." msgstr "" #: glance/api/v2/images.py:381 #, python-format msgid "Pointer `%s` contains \"~\" not part of a recognized escape sequence." msgstr "" #: glance/api/v2/images.py:387 #, python-format msgid "Operation \"%s\" requires a member named \"value\"." msgstr "" #: glance/api/v2/images.py:397 #, python-format msgid "Attribute '%s' is reserved." msgstr "" #: glance/api/v2/images.py:427 #, python-format msgid "Invalid JSON pointer for this resource: '/%s'" msgstr "" #: glance/api/v2/images.py:439 msgid "Unrecognized JSON Schema draft version" msgstr "" #: glance/api/v2/images.py:460 msgid "Request body must be a JSON array of operation objects." msgstr "" #: glance/api/v2/images.py:465 msgid "Operations must be JSON objects." msgstr "" #: glance/api/v2/images.py:487 glance/api/v2/tasks.py:164 #: glance/registry/api/v1/images.py:246 msgid "limit param must be an integer" msgstr "" #: glance/api/v2/images.py:491 glance/api/v2/tasks.py:168 #: glance/registry/api/v1/images.py:249 msgid "limit param must be positive" msgstr "" #: glance/api/v2/images.py:498 glance/api/v2/tasks.py:134 #, python-format msgid "Invalid sort direction: %s" msgstr "" #: glance/api/v2/images.py:505 #, python-format msgid "Invalid status: %s" msgstr "" #: glance/api/v2/images.py:514 #, python-format msgid "Invalid visibility value: %s" msgstr "" #: glance/api/v2/images.py:650 msgid "Descriptive name for the image" msgstr "" #: glance/api/v2/images.py:655 msgid "Status of the image (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:661 msgid "Scope of image accessibility" msgstr "" #: glance/api/v2/images.py:666 msgid "If true, image will not be deletable." msgstr "" #: glance/api/v2/images.py:670 msgid "md5 hash of image contents. (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:675 msgid "Owner of the image" msgstr "" #: glance/api/v2/images.py:680 msgid "Size of image file in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:684 msgid "Virtual size of image in bytes (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:688 msgid "Format of the container" msgstr "" #: glance/api/v2/images.py:693 msgid "Format of the disk" msgstr "" #: glance/api/v2/images.py:698 msgid "Date and time of image registration (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:706 msgid "Date and time of the last image modification (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:712 msgid "List of strings related to the image" msgstr "" #: glance/api/v2/images.py:720 msgid "URL to access the image file kept in external store (READ-ONLY)" msgstr "" #: glance/api/v2/images.py:725 msgid "Amount of ram (in MB) required to boot image." msgstr "" #: glance/api/v2/images.py:729 msgid "Amount of disk space (in GB) required to boot image." msgstr "" #: glance/api/v2/images.py:759 msgid "A set of URLs to access the image file kept in external store" msgstr "" #: glance/api/v2/images.py:798 #, python-format msgid "" "Could not find schema properties file %s. Continuing without custom " "properties" msgstr "" #: glance/api/v2/tasks.py:66 #, python-format msgid "Forbidden to create task. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:109 #, python-format msgid "Failed to find task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:114 #, python-format msgid "Forbidden to get task %(task_id)s. Reason: %(reason)s" msgstr "" #: glance/api/v2/tasks.py:128 msgid "Body expected in request" msgstr "" #: glance/api/v2/tasks.py:143 #, python-format msgid "Invalid status value: %s" msgstr "" #: glance/api/v2/tasks.py:149 #, python-format msgid "Invalid type value: %s" msgstr "" #: glance/api/v2/tasks.py:156 glance/registry/api/v1/images.py:258 msgid "Invalid marker format" msgstr "" #: glance/api/v2/tasks.py:177 #, python-format msgid "Task '%s' is required" msgstr "" #: glance/api/v2/tasks.py:292 msgid "An identifier for the task" msgstr "" #: glance/api/v2/tasks.py:293 msgid "" "^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0" "-9a-fA-F]){12}$" msgstr "" #: glance/api/v2/tasks.py:298 msgid "The type of task represented by this content" msgstr "" #: glance/api/v2/tasks.py:305 msgid "The current status of this task" msgstr "" #: glance/api/v2/tasks.py:315 msgid "The parameters required by task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:319 msgid "The result of current task, JSON blob" msgstr "" #: glance/api/v2/tasks.py:323 msgid "An identifier for the owner of this task" msgstr "" #: glance/api/v2/tasks.py:327 msgid "" "Human-readable informative message only included when appropriate " "(usually on failure)" msgstr "" #: glance/api/v2/tasks.py:332 msgid "Datetime when this resource would be subject to removal" msgstr "" #: glance/api/v2/tasks.py:337 msgid "Datetime when this resource was created" msgstr "" #: glance/api/v2/tasks.py:341 msgid "Datetime when this resource was updated" msgstr "" #: glance/cmd/control.py:102 #, python-format msgid "%(serv)s appears to already be running: %(pid)s" msgstr "" #: glance/cmd/control.py:106 #, python-format msgid "Removing stale pid file %s" msgstr "" #: glance/cmd/control.py:115 msgid "Unable to increase file descriptor limit. Running as non-root?" msgstr "" #: glance/cmd/control.py:161 #, python-format msgid "%(verb)sing %(serv)s" msgstr "" #: glance/cmd/control.py:176 #, python-format msgid "unable to launch %(serv)s. Got error: %(e)s" msgstr "" #: glance/cmd/control.py:206 #, python-format msgid "%(serv)s (pid %(pid)s) is running..." msgstr "" #: glance/cmd/control.py:209 #, python-format msgid "%s is stopped" msgstr "" #: glance/cmd/control.py:225 #, python-format msgid "" "Unable to create pid file %(pid)s. Running as non-root?\n" "Falling back to a temp file, you can stop %(service)s service using:\n" " %(file)s %(server)s stop --pid-file %(fb)s" msgstr "" #: glance/cmd/control.py:255 #, python-format msgid "Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)" msgstr "" #: glance/cmd/control.py:259 #, python-format msgid "Process %d not running" msgstr "" #: glance/cmd/control.py:266 #, python-format msgid "Waited 15 seconds for pid %(pid)s (%(file)s) to die; giving up" msgstr "" #: glance/cmd/control.py:269 #, python-format msgid "%s is already stopped" msgstr "" #: glance/cmd/control.py:346 #, python-format msgid "Supressed respawn as %(serv)s was %(rsn)s." msgstr "" #: glance/cmd/replicator.py:55 #, python-format msgid "" "The image %s is already present on the slave, but our check for it did " "not find it. This indicates that we do not have permissions to see all " "the images on the slave server." msgstr "" #: glance/cmd/replicator.py:105 #, python-format msgid "" "Request: %(method)s http://%(server)s:%(port)s%(url)s with headers " "%(headers)s" msgstr "" #: glance/cmd/replicator.py:118 #, python-format msgid "Response: %(code)s %(status)s %(headers)s" msgstr "" #: glance/cmd/replicator.py:240 glance/cmd/replicator.py:259 msgid "Image post done" msgstr "" #: glance/cmd/replicator.py:282 glance/cmd/replicator.py:319 #: glance/cmd/replicator.py:404 glance/cmd/replicator.py:483 #: glance/cmd/replicator.py:560 msgid "Too few arguments." msgstr "" #: glance/cmd/replicator.py:287 glance/cmd/replicator.py:325 #: glance/cmd/replicator.py:410 glance/cmd/replicator.py:490 #: glance/cmd/replicator.py:567 msgid "Bad format of the given arguments." msgstr "" #: glance/cmd/replicator.py:298 #, python-format msgid "Considering image: %(image)s" msgstr "" #: glance/cmd/replicator.py:303 #, python-format msgid "Total size is %(size)d bytes across %(img_count)d images" msgstr "" #: glance/cmd/replicator.py:333 glance/cmd/replicator.py:423 #, python-format msgid "Considering: %s" msgstr "" #: glance/cmd/replicator.py:337 msgid "... storing" msgstr "" #: glance/cmd/replicator.py:348 msgid "... image is active" msgstr "" #: glance/cmd/replicator.py:368 #, python-format msgid "metadata diff -- master has extra keys: %(keys)s" msgstr "" #: glance/cmd/replicator.py:374 #, python-format msgid "" "metadata diff -- value differs for key %(key)s: master " "\"%(master_value)s\" vs slave \"%(slave_value)s\"" msgstr "" #: glance/cmd/replicator.py:432 #, python-format msgid "Stripping %(header)s from saved metadata" msgstr "" #: glance/cmd/replicator.py:440 #, python-format msgid "Image %s already present" msgstr "" #: glance/cmd/replicator.py:444 glance/cmd/replicator.py:524 #: glance/cmd/replicator.py:590 #, python-format msgid "Stripping %(header)s from slave metadata" msgstr "" #: glance/cmd/replicator.py:449 glance/cmd/replicator.py:529 msgid "... metadata has changed" msgstr "" #: glance/cmd/replicator.py:456 msgid "... dump is missing image data, skipping" msgstr "" #: glance/cmd/replicator.py:505 #, python-format msgid "Considering %(id)s" msgstr "" #: glance/cmd/replicator.py:508 glance/cmd/replicator.py:520 #: glance/cmd/replicator.py:586 #, python-format msgid "Stripping %(header)s from master metadata" msgstr "" #: glance/cmd/replicator.py:535 #, python-format msgid "%s is being synced" msgstr "" #: glance/cmd/replicator.py:596 #, python-format msgid "" "%(image_id)s: field %(key)s differs (source is %(master_value)s, " "destination is %(slave_value)s)" msgstr "" #: glance/cmd/replicator.py:606 #, python-format msgid "%(image_id)s is identical" msgstr "" #: glance/cmd/replicator.py:610 #, python-format msgid "%s: entirely missing from the destination" msgstr "" #: glance/cmd/replicator.py:717 #, python-format msgid "Unknown command: %s" msgstr "" #: glance/common/auth.py:186 glance/common/auth.py:226 #, python-format msgid "Unexpected response: %s" msgstr "" #: glance/common/auth.py:254 #, python-format msgid "Unknown auth strategy '%s'" msgstr "" #: glance/common/auth.py:275 #, python-format msgid "Encountered service with no \"type\": %s" msgstr "" #: glance/common/client.py:240 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:248 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:257 #, python-format msgid "The key file you specified %s does not exist" msgstr "" #: glance/common/client.py:264 #, python-format msgid "The cert file you specified %s does not exist" msgstr "" #: glance/common/client.py:271 #, python-format msgid "The CA file you specified %s does not exist" msgstr "" #: glance/common/client.py:309 #, python-format msgid "Configuring from URL: %s" msgstr "" #: glance/common/client.py:321 #, python-format msgid "Appending doc_root %(doc_root)s to URL %(url)s" msgstr "" #: glance/common/client.py:410 #, python-format msgid "Constructed URL: %s" msgstr "" #: glance/common/config.py:34 msgid "" "Partial name of a pipeline in your paste configuration file with the " "service name removed. For example, if your paste section name is " "[pipeline:glance-api-keystone] use the value \"keystone\"" msgstr "" #: glance/common/config.py:40 msgid "Name of the paste configuration file." msgstr "" #: glance/common/config.py:45 msgid "Supported values for the 'container_format' image attribute" msgstr "" #: glance/common/config.py:52 msgid "Supported values for the 'disk_format' image attribute" msgstr "" #: glance/common/config.py:60 msgid "Time in hours for which a task lives after, either succeeding or failing" msgstr "" #: glance/common/config.py:67 msgid "" "Whether to allow users to specify image properties beyond what the image " "schema provides" msgstr "" #: glance/common/config.py:70 msgid "" "Maximum number of image members per image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:73 msgid "" "Maximum number of properties allowed on an image. Negative values " "evaluate to unlimited." msgstr "" #: glance/common/config.py:76 msgid "" "Maximum number of tags allowed on an image. Negative values evaluate to " "unlimited." msgstr "" #: glance/common/config.py:79 msgid "" "Maximum number of locations allowed on an image. Negative values evaluate" " to unlimited." msgstr "" #: glance/common/config.py:82 msgid "Python module path of data access API" msgstr "" #: glance/common/config.py:84 msgid "" "Default value for the number of items returned by a request if not " "specified explicitly in the request" msgstr "" #: glance/common/config.py:87 msgid "Maximum permissible number of items that could be returned by a request" msgstr "" #: glance/common/config.py:90 msgid "" "Whether to include the backend image storage location in image " "properties. Revealing storage location can be a security risk, so use " "this setting with caution!" msgstr "" #: glance/common/config.py:95 msgid "" "Whether to include the backend image locations in image properties. " "Revealing storage location can be a security risk, so use this setting " "with caution! The overrides show_image_direct_url." msgstr "" #: glance/common/config.py:100 msgid "" "Maximum size of image a user can upload in bytes. Defaults to " "1099511627776 bytes (1 TB)." msgstr "" #: glance/common/config.py:103 msgid "" "Set a system wide quota for every user. This value is the total number " "of bytes that a user can use across all storage systems. A value of 0 " "means unlimited." msgstr "" #: glance/common/config.py:107 msgid "Deploy the v1 OpenStack Images API." msgstr "" #: glance/common/config.py:109 msgid "Deploy the v2 OpenStack Images API." msgstr "" #: glance/common/config.py:111 msgid "Deploy the v1 OpenStack Registry API." msgstr "" #: glance/common/config.py:113 msgid "Deploy the v2 OpenStack Registry API." msgstr "" #: glance/common/config.py:115 msgid "The hostname/IP of the pydev process listening for debug connections" msgstr "" #: glance/common/config.py:118 msgid "The port on which a pydev process is listening for connections." msgstr "" #: glance/common/config.py:121 msgid "" "Key used for encrypting sensitive metadata while talking to the registry " "or database." msgstr "" #: glance/common/config.py:179 #, python-format msgid "Unable to locate paste config file for %s." msgstr "" #: glance/common/config.py:207 #, python-format msgid "Loading %(app_name)s from %(conf_file)s" msgstr "" #: glance/common/config.py:218 #, python-format msgid "" "Unable to load %(app_name)s from configuration file %(conf_file)s.\n" "Got: %(e)r" msgstr "" #: glance/common/exception.py:38 msgid "An unknown exception occurred" msgstr "" #: glance/common/exception.py:63 #, python-format msgid "Missing required credential: %(required)s" msgstr "" #: glance/common/exception.py:67 #, python-format msgid "" "Incorrect auth strategy, expected \"%(expected)s\" but received " "\"%(received)s\"" msgstr "" #: glance/common/exception.py:72 msgid "An object with the specified identifier was not found." msgstr "" #: glance/common/exception.py:76 #, python-format msgid "Unknown scheme '%(scheme)s' found in URI" msgstr "" #: glance/common/exception.py:80 msgid "The Store URI was malformed." msgstr "" #: glance/common/exception.py:84 msgid "An object with the same identifier already exists." msgstr "" #: glance/common/exception.py:88 msgid "An object with the same identifier is currently being operated on." msgstr "" #: glance/common/exception.py:93 msgid "There is not enough disk space on the image storage media." msgstr "" #: glance/common/exception.py:97 #, python-format msgid "" "The size of the data %(image_size)s will exceed the limit. %(remaining)s " "bytes remaining." msgstr "" #: glance/common/exception.py:102 msgid "Permission to write image storage media denied." msgstr "" #: glance/common/exception.py:106 #, python-format msgid "Connect error/bad request to Auth service at URL %(url)s." msgstr "" #: glance/common/exception.py:110 #, python-format msgid "Auth service at URL %(url)s not found." msgstr "" #: glance/common/exception.py:114 msgid "Authorization failed." msgstr "" #: glance/common/exception.py:118 msgid "You are not authenticated." msgstr "" #: glance/common/exception.py:122 glance/common/exception.py:126 msgid "You are not authorized to complete this action." msgstr "" #: glance/common/exception.py:130 #, python-format msgid "Image %(image_id)s is protected and cannot be deleted." msgstr "" #: glance/common/exception.py:134 msgid "Data supplied was not valid." msgstr "" #: glance/common/exception.py:138 #: glance/openstack/common/db/sqlalchemy/utils.py:60 msgid "Sort key supplied was not valid." msgstr "" #: glance/common/exception.py:142 msgid "Invalid configuration in property protection file." msgstr "" #: glance/common/exception.py:146 msgid "Unable to filter using the specified range." msgstr "" #: glance/common/exception.py:150 #, python-format msgid "Attribute '%(property)s' is read-only." msgstr "" #: glance/common/exception.py:154 #, python-format msgid "Attribute '%(property)s' is reserved." msgstr "" #: glance/common/exception.py:158 #, python-format msgid "Redirecting to %(uri)s for authorization." msgstr "" #: glance/common/exception.py:162 msgid "There was an error connecting to a server" msgstr "" #: glance/common/exception.py:166 msgid "There was an error configuring the client." msgstr "" #: glance/common/exception.py:170 #, 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:176 #, python-format msgid "" "The request returned a 413 Request Entity Too Large. This generally means" " that rate limiting or a quota threshold was breached.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:187 msgid "" "The request returned 503 Service Unavilable. This generally occurs on " "service overload or other transient outage." msgstr "" #: glance/common/exception.py:198 msgid "The request returned 500 Internal Server Error." msgstr "" #: glance/common/exception.py:202 #, python-format msgid "" "The request returned an unexpected status: %(status)s.\n" "\n" "The response body:\n" "%(body)s" msgstr "" #: glance/common/exception.py:207 #, python-format msgid "Invalid content type %(content_type)s" msgstr "" #: glance/common/exception.py:211 #, python-format msgid "Registry was not configured correctly on API server. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:216 #, python-format msgid "Store %(store_name)s could not be configured correctly. Reason: %(reason)s" msgstr "" #: glance/common/exception.py:221 #, python-format msgid "" "Driver %(driver_name)s could not be configured correctly. Reason: " "%(reason)s" msgstr "" #: glance/common/exception.py:226 msgid "Deleting images from this store is not supported." msgstr "" #: glance/common/exception.py:230 msgid "Getting images from this store is not supported." msgstr "" #: glance/common/exception.py:234 msgid "Adding images to this store is not supported." msgstr "" #: glance/common/exception.py:238 msgid "Configuration for store failed. Adding images to this store is disabled." msgstr "" #: glance/common/exception.py:243 #, python-format msgid "Maximum redirects (%(redirects)s) was exceeded." msgstr "" #: glance/common/exception.py:247 msgid "Received invalid HTTP redirect." msgstr "" #: glance/common/exception.py:251 msgid "Response from Keystone does not contain a Glance endpoint." msgstr "" #: glance/common/exception.py:255 #, python-format msgid "" "Multiple 'image' service matches for region %(region)s. This generally " "means that a region is required and you have not supplied one." msgstr "" #: glance/common/exception.py:261 #, python-format msgid "Server worker creation failed: %(reason)s." msgstr "" #: glance/common/exception.py:265 #, python-format msgid "Unable to load schema: %(reason)s" msgstr "" #: glance/common/exception.py:269 #, python-format msgid "Provided object does not match schema '%(schema)s': %(reason)s" msgstr "" #: glance/common/exception.py:274 #, python-format msgid "Provided header feature is unsupported: %(feature)s" msgstr "" #: glance/common/exception.py:278 msgid "" "The image cannot be deleted because it is in use through the backend " "store outside of Glance." msgstr "" #: glance/common/exception.py:283 msgid "The provided image is too large." msgstr "" #: glance/common/exception.py:293 #, python-format msgid "" "The limit has been exceeded on the number of allowed image properties. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:298 #, python-format msgid "" "The limit has been exceeded on the number of allowed image tags. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:303 #, python-format msgid "" "The limit has been exceeded on the number of allowed image locations. " "Attempted: %(attempted)s, Maximum: %(maximum)s" msgstr "" #: glance/common/exception.py:308 #, python-format msgid "%(cls)s exception was raised in the last rpc call: %(val)s" msgstr "" #: glance/common/exception.py:312 msgid "An unknown task exception occurred" msgstr "" #: glance/common/exception.py:316 #, python-format msgid "Task with the given id %(task_id)s was not found" msgstr "" #: glance/common/exception.py:320 #, python-format msgid "Provided status of task is unsupported: %(status)s" msgstr "" #: glance/common/exception.py:324 #, python-format msgid "Provided type of task is unsupported: %(type)s" msgstr "" #: glance/common/exception.py:328 #, python-format msgid "Status transition from %(cur_status)s to %(new_status)s is not allowed" msgstr "" #: glance/common/exception.py:333 #, python-format msgid "The location %(location)s already exists" msgstr "" #: glance/common/exception.py:337 glance/store/__init__.py:730 msgid "No image data could be found" msgstr "" #: glance/common/exception.py:341 #, python-format msgid "Invalid value '%(value)s' for parameter '%(param)s': %(extra_msg)s" msgstr "" #: glance/common/exception.py:346 #, python-format msgid "" "Image status transition from %(cur_status)s to %(new_status)s is not " "allowed" msgstr "" #: glance/common/property_utils.py:37 msgid "The location of the property protection file." msgstr "" #: glance/common/property_utils.py:40 msgid "" "This config value indicates whether \"roles\" or \"policies\" are used in" " the property protection file." msgstr "" #: glance/common/property_utils.py:75 #, python-format msgid "Couldn't find property protection file %(file)s: %(error)s." msgstr "" #: glance/common/property_utils.py:82 #, python-format msgid "" "Invalid value '%s' for 'property_protection_rule_format'. The permitted " "values are 'roles' and 'policies'" msgstr "" #: glance/common/property_utils.py:101 #, python-format msgid "" "Multiple policies '%s' not allowedfor a given operation. Policies can be " "combined in the policy file" msgstr "" #: glance/common/property_utils.py:114 #, python-format msgid "" "Malformed property protection rule in [%(prop)s] %(op)s=%(perm)s: '@' and" " '!' are mutually exclusive" msgstr "" #: glance/common/property_utils.py:127 #, python-format msgid "" "Property protection on operation %(operation)s for rule %(rule)s is not " "found. No role will be allowed to perform this operation." msgstr "" #: glance/common/property_utils.py:139 #, python-format msgid "Encountered a malformed property protection rule %(rule)s: %(error)s." msgstr "" #: glance/common/rpc.py:139 msgid "Request must be a list of commands" msgstr "" #: glance/common/rpc.py:144 #, python-format msgid "Bad Command: %s" msgstr "" #: glance/common/rpc.py:151 #, python-format msgid "Wrong command structure: %s" msgstr "" #: glance/common/rpc.py:160 msgid "Command not found" msgstr "" #: glance/common/rpc.py:182 #, python-format msgid "" "RPC Call Error: %(val)s\n" "%(tb)s" msgstr "" #: glance/common/utils.py:103 #, python-format msgid "Error: cooperative_iter exception %s" msgstr "" #: glance/common/utils.py:251 #, python-format msgid "Bad header: %(header_name)s" msgstr "" #: glance/common/utils.py:261 #, python-format msgid "Cannot convert image %(key)s '%(value)s' to an integer." msgstr "" #: glance/common/utils.py:268 #, python-format msgid "Image %(key)s must be >= 0 ('%(value)s' specified)." msgstr "" #: glance/common/utils.py:432 msgid "Read-only access" msgstr "" #: glance/common/utils.py:478 #, python-format msgid "Invalid backend: %s" msgstr "" #: glance/common/utils.py:509 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. Error: %(ioe)s" msgstr "" #: glance/common/utils.py:516 #, python-format msgid "" "There is a problem with your %(error_key_name)s %(error_filename)s. " "Please verify it. OpenSSL error: %(ce)s" msgstr "" #: glance/common/utils.py:530 #, python-format msgid "" "There is a problem with your key pair. Please verify that cert " "%(cert_file)s and key %(key_file)s belong together. OpenSSL error %(ce)s" msgstr "" #: glance/common/wsgi.py:53 msgid "" "Address to bind the server. Useful when selecting a particular network " "interface." msgstr "" #: glance/common/wsgi.py:56 msgid "The port on which the server will listen." msgstr "" #: glance/common/wsgi.py:61 msgid "The backlog value that will be used when creating the TCP listener socket." msgstr "" #: glance/common/wsgi.py:64 msgid "" "The value for the socket option TCP_KEEPIDLE. This is the time in " "seconds that the connection must be idle before TCP starts sending " "keepalive probes." msgstr "" #: glance/common/wsgi.py:67 msgid "CA certificate file to use to verify connecting clients." msgstr "" #: glance/common/wsgi.py:69 msgid "Certificate file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:71 msgid "Private key file to use when starting API server securely." msgstr "" #: glance/common/wsgi.py:77 msgid "" "The number of child process workers that will be created to service API " "requests." msgstr "" #: glance/common/wsgi.py:80 msgid "" "Name of eventlet hub to use. Traditionally, we have only supported " "'poll', however 'selects' may be appropriate for some platforms. See " "http://eventlet.net/doc/hubs.html for more details." msgstr "" #: glance/common/wsgi.py:85 msgid "" "Maximum line size of message headers to be accepted. max_header_line may " "need to be increased when using large tokens (typically those generated " "by the Keystone v3 API with big service catalogs" msgstr "" #: glance/common/wsgi.py:131 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:169 #, python-format msgid "Could not bind to %(host)s:%(port)s after trying for 30 seconds" msgstr "" #: glance/common/wsgi.py:244 glance/openstack/common/service.py:240 #, python-format msgid "Starting %d workers" msgstr "" #: glance/common/wsgi.py:259 #, python-format msgid "Removing dead child %s" msgstr "" #: glance/common/wsgi.py:262 #, python-format msgid "Not respawning child %d, cannot recover from termination" msgstr "" #: glance/common/wsgi.py:266 msgid "All workers have terminated. Exiting" msgstr "" #: glance/common/wsgi.py:274 msgid "Caught keyboard interrupt. Exiting." msgstr "" #: glance/common/wsgi.py:278 msgid "Exited" msgstr "" #: glance/common/wsgi.py:300 #, python-format msgid "Child %d exiting normally" msgstr "" #: glance/common/wsgi.py:305 #, python-format msgid "Started child %s" msgstr "" #: glance/common/wsgi.py:318 #, python-format msgid "eventlet '%s' hub is not available on this platform" msgstr "" #: glance/common/wsgi.py:335 msgid "Starting single process server" msgstr "" #: glance/common/wsgi.py:552 msgid "Malformed JSON in request body." msgstr "" #: glance/common/location_strategy/__init__.py:25 msgid "" "This value sets what strategy will be used to determine the image " "location order. Currently two strategies are packaged with Glance " "'location_order' and 'store_type'." msgstr "" #: glance/common/location_strategy/__init__.py:52 #, python-format msgid "" "%(strategy)s is registered as a module twice. %(module)s is not being " "used." msgstr "" #: glance/common/location_strategy/__init__.py:61 #, python-format msgid "Failed to load location strategy module %(module)s: %(e)s" msgstr "" #: glance/common/location_strategy/__init__.py:74 #, python-format msgid "" "Invalid location_strategy option: %(name)s. The valid strategy option(s) " "is(are): %(strategies)s" msgstr "" #: glance/common/location_strategy/store_type.py:25 msgid "" "The store names to use to get store preference order. The name must be " "registered by one of the stores defined by the 'known_stores' config " "option. This option will be applied when you using 'store_type' option as" " image location strategy defined by the 'location_strategy' config " "option." msgstr "" #: glance/db/__init__.py:64 glance/db/__init__.py:167 glance/db/__init__.py:179 #: glance/db/sqlalchemy/api.py:181 #, python-format msgid "No image found with ID %s" msgstr "" #: glance/db/__init__.py:238 #, python-format msgid "" "The target member %(member_id)s is already associated with image " "%(image_id)s." msgstr "" #: glance/db/__init__.py:255 #, python-format msgid "The specified member %s could not be found" msgstr "" #: glance/db/__init__.py:334 glance/db/__init__.py:360 #: glance/db/__init__.py:377 glance/db/simple/api.py:762 #, python-format msgid "Could not find task %s" msgstr "" #: glance/db/simple/api.py:41 #, python-format msgid "Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s" msgstr "" #: glance/db/simple/api.py:46 #, python-format msgid "Returning %(funcname)s: %(output)s" msgstr "" #: glance/db/simple/api.py:256 glance/db/sqlalchemy/api.py:407 msgid "Unable to filter on a range with a non-numeric value." msgstr "" #: glance/db/simple/api.py:329 #, python-format msgid "Could not find image %s" msgstr "" #: glance/db/simple/api.py:333 msgid "Unable to get deleted image" msgstr "" #: glance/db/simple/api.py:337 msgid "Unable to get unowned image" msgstr "" #: glance/db/simple/api.py:425 glance/db/sqlalchemy/api.py:951 msgid "Image id is required." msgstr "" #: glance/db/simple/api.py:740 glance/db/simple/api.py:790 #: glance/db/sqlalchemy/api.py:1250 #, python-format msgid "No task found with ID %s" msgstr "" #: glance/db/simple/api.py:767 #, python-format msgid "Unable to get deleted task %s" msgstr "" #: glance/db/simple/api.py:772 glance/db/sqlalchemy/api.py:1256 #, python-format msgid "Forbidding request, task %s is not visible" msgstr "" #: glance/db/simple/api.py:890 msgid "Task does not exist" msgstr "" #: glance/db/simple/api.py:912 #, python-format msgid "No task info found with task id %s" msgstr "" #: glance/db/simple/api.py:928 #, python-format msgid "Could not find task info %s" msgstr "" #: glance/db/sqlalchemy/api.py:84 msgid "Attempted to modify image user did not own." msgstr "" #: glance/db/sqlalchemy/api.py:85 msgid "You do not own this image" msgstr "" #: glance/db/sqlalchemy/api.py:187 #, python-format msgid "Forbidding request, image %s not visible" msgstr "" #: glance/db/sqlalchemy/api.py:274 msgid "Id not in sort_keys; is sort_keys unique?" msgstr "" #: glance/db/sqlalchemy/api.py:337 #: glance/openstack/common/db/sqlalchemy/utils.py:121 msgid "Unknown sort direction, must be 'desc' or 'asc'" msgstr "" #: glance/db/sqlalchemy/api.py:682 #: glance/tests/unit/v2/test_registry_client.py:500 #, python-format msgid "" "cannot transition from %(current)s to %(next)s in update (wanted " "from_state=%(from)s)" msgstr "" #: glance/db/sqlalchemy/api.py:1084 #, python-format msgid "TaskInfo was not found for task with id %(task_id)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:96 #, python-format msgid "creating table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/schema.py:102 #, python-format msgid "dropping table %(table)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:58 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:88 #, python-format msgid "Invalid store uri for image: %(image_id)s. Details: %(reason)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:86 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:149 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/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:123 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:185 #, python-format msgid "Badly formed credentials '%(creds)s' in Swift URI" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:135 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:197 #: glance/store/swift.py:246 msgid "Badly formed credentials in Swift URI." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py:152 #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:214 #, python-format msgid "Badly formed S3 URI: %(uri)s" msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:65 msgid "" "'metadata_encryption_key' was not specified in the config file or a " "config file was not specified. This means that this migration is a NOOP." msgstr "" #: glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py:85 #, python-format msgid "Failed to decrypt location value for image %(image_id)s" msgstr "" #: glance/domain/__init__.py:59 #, python-format msgid "new_image() got unexpected keywords %s" msgstr "" #: glance/domain/__init__.py:129 #, python-format msgid "__init__() got unexpected keyword argument '%s'" msgstr "" #: glance/domain/__init__.py:151 #, python-format msgid "Property %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:154 #, python-format msgid "Properties %s must be set prior to saving data." msgstr "" #: glance/domain/__init__.py:171 msgid "Visibility must be either \"public\" or \"private\"" msgstr "" #: glance/domain/__init__.py:190 msgid "Attribute container_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:202 msgid "Attribute disk_format can be only replaced for a queued image." msgstr "" #: glance/domain/__init__.py:214 glance/domain/__init__.py:227 msgid "Cannot be a negative value" msgstr "" #: glance/domain/__init__.py:292 msgid "Status must be \"pending\", \"accepted\" or \"rejected\"." msgstr "" #: glance/domain/__init__.py:356 #, python-format msgid "Task status changed from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:361 #, python-format msgid "Task status failed to change from %(cur_status)s to %(new_status)s" msgstr "" #: glance/domain/__init__.py:391 msgid "task_id is required to create a new TaskDetails object" msgstr "" #: glance/image_cache/__init__.py:34 msgid "The driver to use for image cache management." msgstr "" #: glance/image_cache/__init__.py:36 msgid "The maximum size in bytes that the cache can use." msgstr "" #: glance/image_cache/__init__.py:38 msgid "" "The amount of time to let an image remain in the cache without being " "accessed." msgstr "" #: glance/image_cache/__init__.py:41 msgid "Base directory that the Image Cache uses." msgstr "" #: glance/image_cache/__init__.py:63 #, python-format msgid "Image cache loaded driver '%s'." msgstr "" #: glance/image_cache/__init__.py:66 #, python-format msgid "" "Image cache driver '%(driver_name)s' failed to load. Got error: " "'%(import_err)s." msgstr "" #: glance/image_cache/__init__.py:73 glance/image_cache/__init__.py:92 msgid "Defaulting to SQLite driver." msgstr "" #: glance/image_cache/__init__.py:87 #, python-format msgid "" "Image cache driver '%(driver_module)s' failed to configure. Got error: " "'%(config_err)s" msgstr "" #: glance/image_cache/__init__.py:174 msgid "Image cache has free space, skipping prune..." msgstr "" #: glance/image_cache/__init__.py:178 #, 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:187 #, python-format msgid "Pruning '%(image_id)s' to free %(size)d bytes" msgstr "" #: glance/image_cache/__init__.py:195 #, python-format msgid "" "Pruning finished pruning. Pruned %(total_files_pruned)d and " "%(total_bytes_pruned)d." msgstr "" #: glance/image_cache/__init__.py:234 #, python-format msgid "Tee'ing image '%s' into cache" msgstr "" #: glance/image_cache/__init__.py:253 #, python-format msgid "Checksum verification failed. Aborted caching of image '%s'." msgstr "" #: glance/image_cache/__init__.py:263 #, python-format msgid "" "Exception encountered while tee'ing image '%(image_id)s' into cache: " "%(error)s. Continuing with response." msgstr "" #: glance/image_cache/client.py:117 msgid "" "--os_auth_url option or OS_AUTH_URL environment variable required when " "keystone authentication strategy is enabled\n" msgstr "" #: glance/image_cache/prefetcher.py:46 #, python-format msgid "Image '%s' is not active. Not caching." msgstr "" #: glance/image_cache/prefetcher.py:51 #, python-format msgid "No metadata found for image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:56 #, python-format msgid "Caching image '%s'" msgstr "" #: glance/image_cache/prefetcher.py:68 msgid "Nothing to prefetch." msgstr "" #: glance/image_cache/prefetcher.py:72 #, python-format msgid "Found %d images to prefetch" msgstr "" #: glance/image_cache/prefetcher.py:78 msgid "Failed to successfully cache all images in queue." msgstr "" #: glance/image_cache/prefetcher.py:82 #, python-format msgid "Successfully cached all %d images" msgstr "" #: glance/image_cache/drivers/base.py:54 #, python-format msgid "Failed to read %s from config" msgstr "" #: glance/image_cache/drivers/sqlite.py:39 msgid "" "The path to the sqlite file database that will be used for image cache " "management." msgstr "" #: glance/image_cache/drivers/sqlite.py:121 #, python-format msgid "Failed to initialize the image cache database. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:160 #: glance/image_cache/drivers/xattr.py:144 msgid "Gathering cached image entries." msgstr "" #: glance/image_cache/drivers/sqlite.py:303 #: glance/image_cache/drivers/xattr.py:272 #, python-format msgid "Fetch finished, moving '%(incomplete_path)s' to '%(final_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:327 #: glance/image_cache/drivers/xattr.py:288 #, python-format msgid "" "Fetch of cache file failed (%(e)s), rolling back by moving " "'%(incomplete_path)s' to '%(invalid_path)s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:392 #, python-format msgid "Error executing SQLite call. Got error: %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:408 #: glance/image_cache/drivers/xattr.py:337 #, python-format msgid "Not queueing image '%s'. Already cached." msgstr "" #: glance/image_cache/drivers/sqlite.py:413 #: glance/image_cache/drivers/xattr.py:342 #, python-format msgid "Not queueing image '%s'. Already being written to cache" msgstr "" #: glance/image_cache/drivers/sqlite.py:419 #: glance/image_cache/drivers/xattr.py:348 #, python-format msgid "Not queueing image '%s'. Already queued." msgstr "" #: glance/image_cache/drivers/sqlite.py:437 #, python-format msgid "Removed invalid cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:451 #, python-format msgid "Removed stalled cache file %s" msgstr "" #: glance/image_cache/drivers/sqlite.py:453 #, python-format msgid "Failed to delete file %(path)s. Got error: %(e)s" msgstr "" #: glance/image_cache/drivers/sqlite.py:487 #: glance/image_cache/drivers/xattr.py:438 #, python-format msgid "Deleting image cache file '%s'" msgstr "" #: glance/image_cache/drivers/sqlite.py:490 #: glance/image_cache/drivers/xattr.py:441 #, 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:280 #, python-format msgid "Removing image '%s' from queue after caching it." msgstr "" #: glance/image_cache/drivers/xattr.py:353 #, python-format msgid "Queueing image '%s'." msgstr "" #: glance/image_cache/drivers/xattr.py:383 #, python-format msgid "No grace period, reaping '%(path)s' immediately" msgstr "" #: glance/image_cache/drivers/xattr.py:388 #, python-format msgid "Cache entry '%(path)s' exceeds grace period, (%(age)i s > %(grace)i s)" msgstr "" #: glance/image_cache/drivers/xattr.py:394 #, python-format msgid "Reaped %(reaped)s %(entry_type)s cache entries" msgstr "" #: glance/openstack/common/excutils.py:62 #, python-format msgid "Original exception being dropped: %s" msgstr "" #: glance/openstack/common/excutils.py:91 #, python-format msgid "Unexpected exception occurred %d time(s)... retrying." msgstr "" #: glance/openstack/common/fileutils.py:63 #, python-format msgid "Reloading cached file %s" msgstr "" #: glance/openstack/common/gettextutils.py:297 msgid "Message objects do not support addition." msgstr "" #: glance/openstack/common/gettextutils.py:306 msgid "" "Message objects do not support str() because they may contain non-ascii " "characters. Please use unicode() or translate() instead." msgstr "" #: glance/openstack/common/lockutils.py:103 #, python-format msgid "Could not release the acquired lock `%s`" msgstr "" #: glance/openstack/common/lockutils.py:168 #, python-format msgid "Got semaphore \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:177 #, python-format msgid "Attempting to grab file lock \"%(lock)s\"" msgstr "" #: glance/openstack/common/lockutils.py:187 #, python-format msgid "Created lock path: %s" msgstr "" #: glance/openstack/common/lockutils.py:205 #, python-format msgid "Got file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:209 #, python-format msgid "Released file lock \"%(lock)s\" at %(path)s" msgstr "" #: glance/openstack/common/lockutils.py:247 #, python-format msgid "Got semaphore / lock \"%(function)s\"" msgstr "" #: glance/openstack/common/lockutils.py:251 #, python-format msgid "Semaphore / lock released \"%(function)s\"" msgstr "" #: glance/openstack/common/log.py:313 #, python-format msgid "Deprecated: %s" msgstr "" #: glance/openstack/common/log.py:416 #, python-format msgid "Error loading logging config %(log_config)s: %(err_msg)s" msgstr "" #: glance/openstack/common/log.py:467 #, python-format msgid "syslog facility must be one of: %s" msgstr "" #: glance/openstack/common/log.py:688 #, python-format msgid "Fatal call to deprecated config: %(msg)s" msgstr "" #: glance/openstack/common/loopingcall.py:84 #, python-format msgid "task run outlasted interval by %s sec" msgstr "" #: glance/openstack/common/loopingcall.py:91 msgid "in fixed duration looping call" msgstr "" #: glance/openstack/common/loopingcall.py:131 #, python-format msgid "Dynamic looping call sleeping for %.02f seconds" msgstr "" #: glance/openstack/common/loopingcall.py:138 msgid "in dynamic looping call" msgstr "" #: glance/openstack/common/policy.py:395 #, python-format msgid "Failed to understand rule %(rule)s" msgstr "" #: glance/openstack/common/policy.py:405 #, python-format msgid "No handler for matches of kind %s" msgstr "" #: glance/openstack/common/policy.py:680 #, python-format msgid "Failed to understand rule %(rule)r" msgstr "" #: glance/openstack/common/processutils.py:127 #, python-format msgid "Got unknown keyword args to utils.execute: %r" msgstr "" #: glance/openstack/common/processutils.py:142 #, python-format msgid "Running cmd (subprocess): %s" msgstr "" #: glance/openstack/common/processutils.py:167 #: glance/openstack/common/processutils.py:240 #, python-format msgid "Result was %s" msgstr "" #: glance/openstack/common/processutils.py:179 #, python-format msgid "%r failed. Retrying." msgstr "" #: glance/openstack/common/processutils.py:219 #, python-format msgid "Running cmd (SSH): %s" msgstr "" #: glance/openstack/common/processutils.py:221 msgid "Environment not supported over SSH" msgstr "" #: glance/openstack/common/processutils.py:225 msgid "process_input not supported over SSH" msgstr "" #: glance/openstack/common/service.py:112 #: glance/openstack/common/service.py:275 msgid "Full set of CONF:" msgstr "" #: glance/openstack/common/service.py:121 #: glance/openstack/common/service.py:218 #, python-format msgid "Caught %s, exiting" msgstr "" #: glance/openstack/common/service.py:164 msgid "Parent process has died unexpectedly, exiting" msgstr "" #: glance/openstack/common/service.py:200 msgid "Forking too fast, sleeping" msgstr "" #: glance/openstack/common/service.py:223 msgid "Unhandled exception" msgstr "" #: glance/openstack/common/service.py:230 #, python-format msgid "Started child %d" msgstr "" #: glance/openstack/common/service.py:257 #, python-format msgid "Child %(pid)d killed by signal %(sig)d" msgstr "" #: glance/openstack/common/service.py:261 #, python-format msgid "Child %(pid)s exited with status %(code)d" msgstr "" #: glance/openstack/common/service.py:265 #, python-format msgid "pid %d not in child list" msgstr "" #: glance/openstack/common/service.py:293 #, python-format msgid "Caught %s, stopping children" msgstr "" #: glance/openstack/common/service.py:304 #, python-format msgid "Waiting on %d children to exit" msgstr "" #: glance/openstack/common/strutils.py:86 #, python-format msgid "Unrecognized value '%(val)s', acceptable values are: %(acceptable)s" msgstr "" #: glance/openstack/common/strutils.py:188 #, python-format msgid "Invalid string format: %s" msgstr "" #: glance/openstack/common/strutils.py:195 #, python-format msgid "Unknown byte multiplier: %s" msgstr "" #: glance/openstack/common/db/exception.py:44 msgid "Invalid Parameter: Unicode is not supported by the current database." msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:188 msgid "version should be an integer" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:216 #, python-format msgid "" "Tables \"%s\" have non utf8 collation, please make sure all tables are " "CHARSET=utf8" msgstr "" #: glance/openstack/common/db/sqlalchemy/migration.py:240 msgid "" "The database is not under version control, but has tables. Please stamp " "the current version of the schema manually." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:164 #, python-format msgid "" "There is no `deleted` column in `%s` table. Project doesn't use soft-" "deleted feature." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:176 #, python-format msgid "Unrecognized read_deleted value '%s'" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:183 #, python-format msgid "There is no `project_id` column in `%s` table." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:241 msgid "model should be a subclass of ModelBase" msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:284 #, python-format msgid "" "Please specify column %s in col_name_col_instance param. It is required " "because column has unsupported type by sqlite)." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:290 #, python-format msgid "" "col_name_col_instance param has wrong type of column instance for column " "%s It should be instance of sqlalchemy.Column." msgstr "" #: glance/openstack/common/db/sqlalchemy/utils.py:391 msgid "Unsupported id columns type" msgstr "" #: glance/quota/__init__.py:316 #, python-format msgid "Cleaning up %s after exceeding the quota." msgstr "" #: glance/registry/__init__.py:25 msgid "Address to find the registry server." msgstr "" #: glance/registry/__init__.py:27 msgid "Port the registry server is listening on." msgstr "" #: glance/registry/api/v1/images.py:105 #, python-format msgid "Invalid marker. Image %(id)s could not be found." msgstr "" #: glance/registry/api/v1/images.py:107 glance/registry/api/v1/images.py:112 msgid "Invalid marker. Image could not be found." msgstr "" #: glance/registry/api/v1/images.py:110 glance/registry/api/v1/images.py:328 #: glance/registry/api/v1/images.py:359 glance/registry/api/v1/images.py:478 #: glance/registry/api/v1/members.py:72 glance/registry/api/v1/members.py:106 #: glance/registry/api/v1/members.py:219 glance/registry/api/v1/members.py:279 #, python-format msgid "Access denied to image %(id)s but returning 'not found'" msgstr "" #: glance/registry/api/v1/images.py:115 msgid "Unable to get images" msgstr "" #: glance/registry/api/v1/images.py:147 msgid "Returning image list" msgstr "" #: glance/registry/api/v1/images.py:165 msgid "Returning detailed image list" msgstr "" #: glance/registry/api/v1/images.py:216 msgid "Unrecognized changes-since value" msgstr "" #: glance/registry/api/v1/images.py:221 msgid "protected must be True, or False" msgstr "" #: glance/registry/api/v1/images.py:268 #, python-format msgid "Unsupported sort_key. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:277 #, python-format msgid "Unsupported sort_dir. Acceptable values: %s" msgstr "" #: glance/registry/api/v1/images.py:303 msgid "is_public must be None, True, or False" msgstr "" #: glance/registry/api/v1/images.py:319 #, python-format msgid "Successfully retrieved image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:322 glance/registry/api/v1/images.py:363 #: glance/registry/api/v1/images.py:466 glance/registry/api/v1/members.py:66 #: glance/registry/api/v1/members.py:100 glance/registry/api/v1/members.py:213 #: glance/registry/api/v1/members.py:273 #, python-format msgid "Image %(id)s not found" msgstr "" #: glance/registry/api/v1/images.py:332 #, python-format msgid "Unable to show image %s" msgstr "" #: glance/registry/api/v1/images.py:349 #, python-format msgid "Successfully deleted image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:353 #, python-format msgid "Delete denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:367 #, python-format msgid "Unable to delete image %s" msgstr "" #: glance/registry/api/v1/images.py:392 #, python-format msgid "Rejecting image creation request for invalid image id '%(bad_id)s'" msgstr "" #: glance/registry/api/v1/images.py:395 msgid "Invalid image id format" msgstr "" #: glance/registry/api/v1/images.py:405 #, python-format msgid "Successfully created image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:409 #, python-format msgid "Image with identifier %s already exists!" msgstr "" #: glance/registry/api/v1/images.py:413 #, python-format msgid "Failed to add image metadata. Got error: %(e)s" msgstr "" #: glance/registry/api/v1/images.py:418 #, python-format msgid "Unable to create image %s" msgstr "" #: glance/registry/api/v1/images.py:443 #, python-format msgid "Updating image %(id)s with metadata: %(image_data)r" msgstr "" #: glance/registry/api/v1/images.py:457 #, python-format msgid "Updating metadata for image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:472 #, python-format msgid "Update denied for public image %(id)s" msgstr "" #: glance/registry/api/v1/images.py:489 #, python-format msgid "Unable to update image %s" msgstr "" #: glance/registry/api/v1/members.py:77 #, python-format msgid "Returning member list for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:112 glance/registry/api/v1/members.py:225 #: glance/registry/api/v1/members.py:285 #, python-format msgid "User lacks permission to share image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:114 glance/registry/api/v1/members.py:227 #: glance/registry/api/v1/members.py:287 msgid "No permission to share that image" msgstr "" #: glance/registry/api/v1/members.py:122 glance/registry/api/v1/members.py:138 #: glance/registry/api/v1/members.py:237 #, python-format msgid "Invalid membership association specified for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:125 glance/registry/api/v1/members.py:141 #: glance/registry/api/v1/members.py:240 #, python-format msgid "Invalid membership association: %s" msgstr "" #: glance/registry/api/v1/members.py:189 #, python-format msgid "Successfully updated memberships for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:258 #, python-format msgid "Successfully updated a membership for image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:297 #, python-format msgid "%(id)s is not a member of image %(image_id)s" msgstr "" #: glance/registry/api/v1/members.py:300 glance/registry/api/v1/members.py:317 msgid "Membership could not be found." msgstr "" #: glance/registry/api/v1/members.py:304 #, python-format msgid "Successfully deleted a membership from image %(id)s" msgstr "" #: glance/registry/api/v1/members.py:315 #, python-format msgid "Member %(id)s not found" msgstr "" #: glance/registry/api/v1/members.py:320 #, python-format msgid "Returning list of images shared with member %(id)s" msgstr "" #: glance/registry/api/v2/rpc.py:42 #, python-format msgid "Registry service can't use %s" msgstr "" #: glance/registry/client/__init__.py:20 msgid "" "The protocol to use for communication with the registry server. Either " "http or https." msgstr "" #: glance/registry/client/__init__.py:23 msgid "The path to the key file to use in SSL connections to the registry server." msgstr "" #: glance/registry/client/__init__.py:26 msgid "" "The path to the cert file to use in SSL connections to the registry " "server." msgstr "" #: glance/registry/client/__init__.py:29 msgid "" "The path to the certifying authority cert file to use in SSL connections " "to the registry server." msgstr "" #: glance/registry/client/__init__.py:32 msgid "" "When using SSL in connections to the registry server, do not require " "validation via a certifying authority." msgstr "" #: glance/registry/client/__init__.py:36 msgid "" "The period of time, in seconds, that the API server will wait for a " "registry request to complete. A value of 0 implies no timeout." msgstr "" #: glance/registry/client/__init__.py:43 glance/store/__init__.py:55 msgid "" "Whether to pass through the user token when making requests to the " "registry." msgstr "" #: glance/registry/client/__init__.py:46 msgid "The administrators user name." msgstr "" #: glance/registry/client/__init__.py:48 msgid "The administrators password." msgstr "" #: glance/registry/client/__init__.py:50 msgid "The tenant name of the administrative user." msgstr "" #: glance/registry/client/__init__.py:52 msgid "The URL to the keystone service." msgstr "" #: glance/registry/client/__init__.py:54 msgid "The strategy to use for authentication." msgstr "" #: glance/registry/client/__init__.py:56 msgid "The region for the authentication service." msgstr "" #: glance/registry/client/v1/api.py:33 msgid "" "Whether to pass through headers containing user and tenant information " "when making requests to the registry. This allows the registry to use the" " context middleware without the keystoneclients' auth_token middleware, " "removing calls to the keystone auth service. It is recommended that when " "using this option, secure communication between glance api and glance " "registry is ensured by means other than auth_token middleware." msgstr "" #: glance/registry/client/v1/api.py:78 glance/registry/client/v2/api.py:60 msgid "Configuration option was not valid" msgstr "" #: glance/registry/client/v1/api.py:82 glance/registry/client/v2/api.py:64 msgid "Could not find required configuration option" msgstr "" #: glance/registry/client/v1/api.py:159 msgid "Adding image metadata..." msgstr "" #: glance/registry/client/v1/api.py:166 #, python-format msgid "Updating image metadata for image %s..." msgstr "" #: glance/registry/client/v1/api.py:173 #, python-format msgid "Deleting image metadata for image %s..." msgstr "" #: glance/registry/client/v1/client.py:110 #, python-format msgid "" "Registry request %(method)s %(action)s HTTP %(status)s request id " "%(request_id)s" msgstr "" #: glance/registry/client/v1/client.py:118 #, python-format msgid "Registry client request %(method)s %(action)s raised %(exc_name)s" msgstr "" #: glance/store/__init__.py:40 msgid "" "List of which store classes and store class locations are currently known" " to glance at startup." msgstr "" #: glance/store/__init__.py:43 msgid "" "Default scheme to use to store image data. The scheme must be registered " "by one of the stores defined by the 'known_stores' config option." msgstr "" #: glance/store/__init__.py:53 msgid "Turn on/off delayed delete." msgstr "" #: glance/store/__init__.py:191 #, python-format msgid "%s Skipping store driver." msgstr "" #: glance/store/__init__.py:196 #, python-format msgid "" "%s not found in `known_store`. Stores need to be explicitly enabled in " "the configuration file." msgstr "" #: glance/store/__init__.py:318 #, python-format msgid "Failed to delete image %s in store from URI" msgstr "" #: glance/store/__init__.py:324 #, python-format msgid "Failed to delete image %(image_id)s from store (%(error)s)" msgstr "" #: glance/store/__init__.py:359 #, python-format msgid "" "The image metadata key %(key)s has an invalid type of %(val)s. Only " "dict, list, and unicode are supported." msgstr "" #: glance/store/__init__.py:383 #, python-format msgid "" "The storage driver %(store)s returned invalid metadata %(metadata)s. This" " must be a dictionary type" msgstr "" #: glance/store/__init__.py:392 #, python-format msgid "" "A bad metadata structure was returned from the %(store)s storage driver: " "%(metadata)s. %(error)s." msgstr "" #: glance/store/__init__.py:419 msgid "Skipping store.set_acls... not implemented." msgstr "" #: glance/store/__init__.py:469 #, python-format msgid "Invalid location: %s" msgstr "" #: glance/store/__init__.py:667 #, python-format msgid "Original locations is not empty: %s" msgstr "" #: glance/store/__init__.py:739 #, python-format msgid "Get image %(id)s data failed: %(err)s." msgstr "" #: glance/store/__init__.py:744 #, python-format msgid "Glance tried all locations to get data for image %s but all have failed." msgstr "" #: glance/store/base.py:35 glance/tests/unit/test_store_base.py:51 #, python-format msgid "Caught '%(exception)s' exception." msgstr "" #: glance/store/base.py:56 #, python-format msgid "Failed to configure store correctly: %s Disabling add method." msgstr "" #: glance/store/cinder.py:88 #, python-format msgid "Cinderclient connection created using URL: %s" msgstr "" #: glance/store/cinder.py:118 msgid "URI must start with cinder://" msgstr "" #: glance/store/cinder.py:126 #, python-format msgid "URI contains invalid volume ID: %s" msgstr "" #: glance/store/cinder.py:149 msgid "Cinder storage requires a context." msgstr "" #: glance/store/cinder.py:153 msgid "Cinder storage requires a service catalog." msgstr "" #: glance/store/cinder.py:175 #, python-format msgid "Failed to get image size due to volume can not be found: %s" msgstr "" #: glance/store/cinder.py:180 #, python-format msgid "Failed to get image size due to internal error: %s" msgstr "" #: glance/store/filesystem.py:41 msgid "Directory to which the Filesystem backend store writes images." msgstr "" #: glance/store/filesystem.py:44 msgid "" "List of directories and its priorities to which the Filesystem backend " "store writes images." msgstr "" #: glance/store/filesystem.py:47 msgid "" "The path to a file which contains the metadata to be returned with any " "location associated with this store. The file must contain a valid JSON " "dict." msgstr "" #: glance/store/filesystem.py:78 #, python-format msgid "No path specified in URI: %s" msgstr "" #: glance/store/filesystem.py:131 #, python-format msgid "Permission to write in %s denied" msgstr "" #: glance/store/filesystem.py:148 #, python-format msgid "Directory to write image files does not exist (%s). Creating." msgstr "" #: glance/store/filesystem.py:162 #, python-format msgid "Unable to create datadir: %s" msgstr "" #: glance/store/filesystem.py:176 msgid "" "Specify at least 'filesystem_store_datadir' or " "'filesystem_store_datadirs' option" msgstr "" #: glance/store/filesystem.py:183 msgid "" "Specify either 'filesystem_store_datadir' or 'filesystem_store_datadirs' " "option" msgstr "" #: glance/store/filesystem.py:220 #, python-format msgid "" "Directory %(datadir_path)s specified multiple times in " "filesystem_store_datadirs option of filesystem configuration" msgstr "" #: glance/store/filesystem.py:245 #, python-format msgid "Invalid priority value %(priority)s in filesystem configuration" msgstr "" #: glance/store/filesystem.py:252 msgid "Invalid directory specified in filesystem configuration" msgstr "" #: glance/store/filesystem.py:264 #, python-format msgid "Image file %s not found" msgstr "" #: glance/store/filesystem.py:279 #, python-format msgid "" "The JSON in the metadata file %(file)s could not be used: %(error)s An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:286 #, python-format msgid "" "The path for the metadata file %(file)s could not be opened: %(error)s " "An empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:293 #, python-format msgid "" "An error occurred processing the storage systems meta data file: %s. An " "empty dictionary will be returned to the client." msgstr "" #: glance/store/filesystem.py:309 #, python-format msgid "Found image at %s. Returning in ChunkedFile." msgstr "" #: glance/store/filesystem.py:324 #, python-format msgid "Found image at %s." msgstr "" #: glance/store/filesystem.py:343 #, python-format msgid "Deleting image at %(fn)s" msgstr "" #: glance/store/filesystem.py:346 #, python-format msgid "You cannot delete file %s" msgstr "" #: glance/store/filesystem.py:348 #, python-format msgid "Image file %s does not exist" msgstr "" #: glance/store/filesystem.py:393 #, python-format msgid "" "There is no enough disk space left on the image storage media. " "requested=%s" msgstr "" #: glance/store/filesystem.py:424 #, python-format msgid "Image file %s already exists!" msgstr "" #: glance/store/filesystem.py:450 #, python-format msgid "" "Wrote %(bytes_written)d bytes to %(filepath)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/filesystem.py:462 #, python-format msgid "Unable to remove partial image data for image %(id)s: %(error)s" msgstr "" #: glance/store/gridfs.py:97 msgid "Missing dependencies: pymongo" msgstr "" #: glance/store/gridfs.py:113 glance/store/s3.py:252 glance/store/swift.py:366 #: glance/store/vmware_datastore.py:235 #, python-format msgid "Could not find %(param)s in configuration options." msgstr "" #: glance/store/gridfs.py:157 #, python-format msgid "Could not find %s image in GridFS" msgstr "" #: glance/store/gridfs.py:180 #, python-format msgid "GridFS already has an image at location %s" msgstr "" #: glance/store/gridfs.py:183 #, python-format msgid "Adding a new image to GridFS with id %(id)s and size %(size)s" msgstr "" #: glance/store/gridfs.py:196 #, python-format msgid "Uploaded image %(id)s, md5 %(md5)s, length %(length)s to GridFS" msgstr "" #: glance/store/http.py:81 #, python-format msgid "Credentials '%s' not well-formatted." msgstr "" #: glance/store/http.py:88 msgid "No address specified in HTTP URL" msgstr "" #: glance/store/http.py:154 #, python-format msgid "The HTTP URL exceeded %s maximum redirects." msgstr "" #: glance/store/http.py:166 #, python-format msgid "HTTP URL returned a %s status code." msgstr "" #: glance/store/http.py:173 #, python-format msgid "The HTTP URL attempted to redirect with an invalid %s status code." msgstr "" #: glance/store/location.py:85 #, python-format msgid "Registering scheme %(k)s with %(v)s" msgstr "" #: glance/store/rbd.py:51 msgid "" "RADOS images will be chunked into objects of this size (in megabytes). " "For best performance, this should be a power of two." msgstr "" #: glance/store/rbd.py:55 msgid "RADOS pool in which images are stored." msgstr "" #: glance/store/rbd.py:57 msgid "" "RADOS user to authenticate as (only applicable if using Cephx. If ," " a default will be chosen based on the client. section in " "rbd_store_ceph_conf)." msgstr "" #: glance/store/rbd.py:61 msgid "" "Ceph configuration file path. If , librados will locate the default" " config. If using cephx authentication, this file should include a " "reference to the right keyring in a client. section." msgstr "" #: glance/store/rbd.py:107 msgid "URI must start with rbd://" msgstr "" #: glance/store/rbd.py:108 glance/store/rbd.py:117 glance/store/rbd.py:130 #: glance/store/rbd.py:136 #, python-format msgid "Invalid URI: %(uri)s: %(reason)s" msgstr "" #: glance/store/rbd.py:116 msgid "URI contains non-ascii characters" msgstr "" #: glance/store/rbd.py:129 msgid "URI must have exactly 1 or 4 components" msgstr "" #: glance/store/rbd.py:135 msgid "URI cannot contain empty components" msgstr "" #: glance/store/rbd.py:171 glance/store/rbd.py:235 glance/store/rbd.py:295 #, python-format msgid "RBD image %s does not exist" msgstr "" #: glance/store/rbd.py:198 glance/store/sheepdog.py:197 #: glance/store/sheepdog.py:205 #, python-format msgid "Error in store configuration: %s" msgstr "" #: glance/store/rbd.py:282 #, python-format msgid "snapshot %(image)s@%(snap)s could not be unprotected because it is in use" msgstr "" #: glance/store/rbd.py:297 #, python-format msgid "image %s could not be removed because it is in use" msgstr "" #: glance/store/rbd.py:328 msgid "" "since image size is zero we will be doing resize-before-write for each " "chunk which will be considerably slower than normal" msgstr "" #: glance/store/rbd.py:337 #, python-format msgid "RBD image %s already exists" msgstr "" #: glance/store/rbd.py:353 #, python-format msgid "resizing image to %s KiB" msgstr "" #: glance/store/rbd.py:356 #, python-format msgid "writing chunk at offset %s" msgstr "" #: glance/store/s3.py:37 msgid "The host where the S3 server is listening." msgstr "" #: glance/store/s3.py:39 msgid "The S3 query token access key." msgstr "" #: glance/store/s3.py:41 msgid "The S3 query token secret key." msgstr "" #: glance/store/s3.py:43 msgid "The S3 bucket to be used to store the Glance data." msgstr "" #: glance/store/s3.py:45 msgid "" "The local directory where uploads will be staged before they are " "transferred into S3." msgstr "" #: glance/store/s3.py:48 msgid "" "A boolean to determine if the S3 bucket should be created on upload if it" " does not exist or if an error should be returned to the user." msgstr "" #: glance/store/s3.py:52 msgid "" "The S3 calling format used to determine the bucket. Either subdomain or " "path can be used." msgstr "" #: glance/store/s3.py:115 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:123 #, python-format msgid "Invalid store uri: %s" msgstr "" #: glance/store/s3.py:149 #, python-format msgid "Badly formed S3 credentials %s" msgstr "" #: glance/store/s3.py:162 msgid "Badly formed S3 URI. Missing s3 service URL." msgstr "" #: glance/store/s3.py:165 #, python-format msgid "Badly formed S3 URI: %s" msgstr "" #: glance/store/s3.py:307 #, 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:367 #, python-format msgid "S3 already has an image at location %s" msgstr "" #: glance/store/s3.py:371 #, 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:393 #, python-format msgid "Writing request body file to temporary file for %s" msgstr "" #: glance/store/s3.py:405 #, python-format msgid "Uploading temporary file to S3 for %s" msgstr "" #: glance/store/s3.py:414 #, python-format msgid "" "Wrote %(size)d bytes to S3 key named %(obj_name)s with checksum " "%(checksum_hex)s" msgstr "" #: glance/store/s3.py:442 #, 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:464 #, python-format msgid "Could not find bucket with ID %s" msgstr "" #: glance/store/s3.py:505 #, python-format msgid "" "Failed to add bucket to S3.\n" "Got error from S3: %(e)s" msgstr "" #: glance/store/s3.py:509 #, python-format msgid "" "The bucket %(bucket)s does not exist in S3. Please set the " "s3_store_create_bucket_on_put option to add bucket to S3 automatically." msgstr "" #: glance/store/s3.py:528 #, python-format msgid "Could not find key %(obj)s in bucket %(bucket)s" msgstr "" #: glance/store/sheepdog.py:42 msgid "" "Images will be chunked into objects of this size (in megabytes). For best" " performance, this should be a power of two." msgstr "" #: glance/store/sheepdog.py:46 msgid "Port of sheep daemon." msgstr "" #: glance/store/sheepdog.py:48 msgid "IP address of sheep daemon." msgstr "" #: glance/store/sheepdog.py:225 glance/store/sheepdog.py:244 #: glance/store/sheepdog.py:305 #, python-format msgid "Sheepdog image %s does not exist" msgstr "" #: glance/store/sheepdog.py:266 #, python-format msgid "Sheepdog image %s already exists" msgstr "" #: glance/store/swift.py:49 msgid "Whether to use ServiceNET to communicate with the Swift storage servers." msgstr "" #: glance/store/swift.py:52 msgid "The address where the Swift authentication service is listening." msgstr "" #: glance/store/swift.py:55 msgid "The user to authenticate against the Swift authentication service." msgstr "" #: glance/store/swift.py:58 msgid "" "Auth key for the user authenticating against the Swift authentication " "service." msgstr "" #: glance/store/swift.py:61 msgid "" "Version of the authentication service to use. Valid versions are 2 for " "keystone and 1 for swauth and rackspace." msgstr "" #: glance/store/swift.py:65 msgid "" "If True, swiftclient won't check for a valid SSL certificate when " "authenticating." msgstr "" #: glance/store/swift.py:68 msgid "" "The region of the swift endpoint to be used for single tenant. This " "setting is only necessary if the tenant has multiple swift endpoints." msgstr "" #: glance/store/swift.py:72 msgid "" "A string giving the endpoint type of the swift service to use (publicURL," " adminURL or internalURL). This setting is only used if " "swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:77 msgid "" "A string giving the service type of the swift service to use. This " "setting is only used if swift_store_auth_version is 2." msgstr "" #: glance/store/swift.py:82 msgid "" "Container within the account that the account should use for storing " "images in Swift." msgstr "" #: glance/store/swift.py:86 msgid "" "The size, in MB, that Glance will start chunking image files and do a " "large object manifest in Swift." msgstr "" #: glance/store/swift.py:90 msgid "" "The amount of data written to a temporary disk buffer during the process " "of chunking the image file." msgstr "" #: glance/store/swift.py:93 msgid "" "A boolean value that determines if we create the container if it does not" " exist." msgstr "" #: glance/store/swift.py:96 msgid "" "If set to True, enables multi-tenant storage mode which causes Glance " "images to be stored in tenant specific Swift accounts." msgstr "" #: glance/store/swift.py:100 msgid "" "A list of tenants that will be granted read/write access on all Swift " "containers created by Glance in multi-tenant mode." msgstr "" #: glance/store/swift.py:104 msgid "" "If set to False, disables SSL layer compression of https swift requests. " "Setting to False may improve performance for images which are already in " "a compressed format, eg qcow2." msgstr "" #: glance/store/swift.py:109 msgid "" "The number of times a Swift download will be retried before the request " "fails." msgstr "" #: glance/store/swift.py:129 #, python-format msgid "Swift exception raised %s" msgstr "" #: glance/store/swift.py:134 #, python-format msgid "Stopping Swift retries after %d attempts" msgstr "" #: glance/store/swift.py:139 #, python-format msgid "" "Retrying Swift connection (%(retries)d/%(max_retries)d) with " "range=%(start)d-%(end)d" msgstr "" #: glance/store/swift.py:214 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:220 #, python-format msgid "Invalid store URI: %(reason)s" msgstr "" #: glance/store/swift.py:264 msgid "Badly formed Swift URI." msgstr "" #: glance/store/swift.py:328 #, python-format msgid "Swift could not find object %s." msgstr "" #: glance/store/swift.py:375 #, python-format msgid "Deleting chunk %s" msgstr "" #: glance/store/swift.py:379 #, python-format msgid "Failed to delete orphaned chunk %(container)s/%(chunk)s" msgstr "" #: glance/store/swift.py:391 #, python-format msgid "Adding image object '%(obj_name)s' to Swift" msgstr "" #: glance/store/swift.py:411 msgid "Cannot determine image size. Adding as a segmented object to Swift." msgstr "" #: glance/store/swift.py:440 msgid "Error during chunked upload to backend, deleting stale chunks" msgstr "" #: glance/store/swift.py:447 #, python-format msgid "" "Wrote chunk %(chunk_name)s (%(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:461 msgid "Deleting final zero-length chunk" msgstr "" #: glance/store/swift.py:498 msgid "Swift already has an image at this location" msgstr "" #: glance/store/swift.py:500 #, python-format msgid "" "Failed to add object to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:541 glance/store/swift.py:702 msgid "Swift could not find image at URI." msgstr "" #: glance/store/swift.py:562 #, python-format msgid "" "Failed to add container to Swift.\n" "Got error from Swift: %(e)s" msgstr "" #: glance/store/swift.py:566 #, 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 "" #: glance/store/swift.py:610 msgid "Location is missing user:password information." msgstr "" #: glance/store/swift.py:622 #, python-format msgid "Badly formed tenant:user '%(user)s' in Swift URI" msgstr "" #: glance/store/swift.py:649 msgid "Multi-tenant Swift storage requires a context." msgstr "" #: glance/store/swift.py:653 msgid "Multi-tenant Swift storage requires a service catalog." msgstr "" #: glance/store/vmware_datastore.py:48 msgid "" "ESX/ESXi or vCenter Server target system. The server value can be an IP " "address or a DNS name." msgstr "" #: glance/store/vmware_datastore.py:51 msgid "Username for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:54 msgid "Password for authenticating with VMware ESX/VC server." msgstr "" #: glance/store/vmware_datastore.py:59 msgid "" "Inventory path to a datacenter. If the vmware_server_host specified is an" " ESX/ESXi, the vmware_datacenter_path is optional. If specified, it " "should be \"ha-datacenter\"." msgstr "" #: glance/store/vmware_datastore.py:64 msgid "Datastore associated with the datacenter." msgstr "" #: glance/store/vmware_datastore.py:67 msgid "" "Number of times VMware ESX/VC server API must be retried upon connection " "related issues." msgstr "" #: glance/store/vmware_datastore.py:71 msgid "" "The interval used for polling remote tasks invoked on VMware ESX/VC " "server." msgstr "" #: glance/store/vmware_datastore.py:75 msgid "" "The name of the directory where the glance images will be stored in the " "VMware datastore." msgstr "" #: glance/store/vmware_datastore.py:79 msgid "Allow to perform insecure SSL requests to ESX/VC." msgstr "" #: glance/store/vmware_datastore.py:165 #, python-format msgid "URI %(uri)s must start with %(scheme)s://" msgstr "" #: glance/store/vmware_datastore.py:181 #, python-format msgid "Badly formed VMware datastore URI %(uri)s." msgstr "" #: glance/store/vmware_datastore.py:222 #, python-format msgid "Could not find datastore %(ds_name)s in datacenter %(dc_path)s" msgstr "" #: glance/store/vmware_datastore.py:280 glance/store/vmware_datastore.py:288 #, python-format msgid "Failed to upload content of image %(image)s" msgstr "" #: glance/store/vmware_datastore.py:284 #, python-format msgid "Image file %(image_id)s already exists!" msgstr "" #: glance/store/vmware_datastore.py:359 #, python-format msgid "Failed to delete image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:364 #, python-format msgid "The HTTP URL exceeded %(max_redirects)s maximum redirects." msgstr "" #: glance/store/vmware_datastore.py:374 #, python-format msgid "Failed to access image %(image)s content." msgstr "" #: glance/store/vmware_datastore.py:378 msgid "VMware datastore could not find image at URI." msgstr "" #: glance/store/vmware_datastore.py:381 #, python-format msgid "HTTP request returned a %(status)s status code." msgstr "" #: glance/store/vmware_datastore.py:388 #, python-format msgid "" "The HTTP URL %(path)s attempted to redirect with an invalid %(status)s " "status code." msgstr "" #: glance/tests/unit/test_migrations.py:927 #, python-format msgid "location: %s data lost" msgstr "" glance-2014.1/glance/openstack/0000775000175400017540000000000012323736427017421 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/openstack/common/0000775000175400017540000000000012323736427020711 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/openstack/common/fileutils.py0000664000175400017540000000750412323736226023266 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import contextlib import errno import os import tempfile from glance.openstack.common import excutils from glance.openstack.common.gettextutils import _ from glance.openstack.common import log as logging LOG = logging.getLogger(__name__) _FILE_CACHE = {} def ensure_tree(path): """Create a directory (and any ancestor directories required) :param path: Directory to create """ try: os.makedirs(path) except OSError as exc: if exc.errno == errno.EEXIST: if not os.path.isdir(path): raise else: raise def read_cached_file(filename, force_reload=False): """Read from a file if it has been modified. :param force_reload: Whether to reload the file. :returns: A tuple with a boolean specifying if the data is fresh or not. """ global _FILE_CACHE if force_reload and filename in _FILE_CACHE: del _FILE_CACHE[filename] reloaded = False mtime = os.path.getmtime(filename) cache_info = _FILE_CACHE.setdefault(filename, {}) if not cache_info or mtime > cache_info.get('mtime', 0): LOG.debug(_("Reloading cached file %s") % filename) with open(filename) as fap: cache_info['data'] = fap.read() cache_info['mtime'] = mtime reloaded = True return (reloaded, cache_info['data']) def delete_if_exists(path, remove=os.unlink): """Delete a file, but ignore file not found error. :param path: File to delete :param remove: Optional function to remove passed path """ try: remove(path) except OSError as e: if e.errno != errno.ENOENT: raise @contextlib.contextmanager def remove_path_on_error(path, remove=delete_if_exists): """Protect code that wants to operate on PATH atomically. Any exception will cause PATH to be removed. :param path: File to work with :param remove: Optional function to remove passed path """ try: yield except Exception: with excutils.save_and_reraise_exception(): remove(path) def file_open(*args, **kwargs): """Open file see built-in file() documentation for more details Note: The reason this is kept in a separate module is to easily be able to provide a stub module that doesn't alter system state at all (for unit tests) """ return file(*args, **kwargs) def write_to_tempfile(content, path=None, suffix='', prefix='tmp'): """Create temporary file or use existing file. This util is needed for creating temporary file with specified content, suffix and prefix. If path is not None, it will be used for writing content. If the path doesn't exist it'll be created. :param content: content for temporary file. :param path: same as parameter 'dir' for mkstemp :param suffix: same as parameter 'suffix' for mkstemp :param prefix: same as parameter 'prefix' for mkstemp For example: it can be used in database tests for creating configuration files. """ if path: ensure_tree(path) (fd, path) = tempfile.mkstemp(suffix=suffix, dir=path, prefix=prefix) try: os.write(fd, content) finally: os.close(fd) return path glance-2014.1/glance/openstack/common/network_utils.py0000664000175400017540000000422212323736226024171 0ustar jenkinsjenkins00000000000000# vim: tabstop=4 shiftwidth=4 softtabstop=4 # Copyright 2012 OpenStack Foundation. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ Network-related utilities and helper functions. """ from glance.openstack.common import log as logging LOG = logging.getLogger(__name__) def parse_host_port(address, default_port=None): """ Interpret a string as a host:port pair. An IPv6 address MUST be escaped if accompanied by a port, because otherwise ambiguity ensues: 2001:db8:85a3::8a2e:370:7334 means both [2001:db8:85a3::8a2e:370:7334] and [2001:db8:85a3::8a2e:370]:7334. >>> parse_host_port('server01:80') ('server01', 80) >>> parse_host_port('server01') ('server01', None) >>> parse_host_port('server01', default_port=1234) ('server01', 1234) >>> parse_host_port('[::1]:80') ('::1', 80) >>> parse_host_port('[::1]') ('::1', None) >>> parse_host_port('[::1]', default_port=1234) ('::1', 1234) >>> parse_host_port('2001:db8:85a3::8a2e:370:7334', default_port=1234) ('2001:db8:85a3::8a2e:370:7334', 1234) """ if address[0] == '[': # Escaped ipv6 _host, _port = address[1:].split(']') host = _host if ':' in _port: port = _port.split(':')[1] else: port = default_port else: if address.count(':') == 1: host, port = address.split(':') else: # 0 means ipv4, >1 means ipv6. # We prohibit unescaped ipv6 addresses with port. host = address port = default_port return (host, None if port is None else int(port)) glance-2014.1/glance/openstack/common/units.py0000664000175400017540000000163012323736226022422 0ustar jenkinsjenkins00000000000000# Copyright 2013 IBM Corp # 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. """ Unit constants """ #Binary unit constants. Ki = 1024 Mi = 1024 ** 2 Gi = 1024 ** 3 Ti = 1024 ** 4 Pi = 1024 ** 5 Ei = 1024 ** 6 Zi = 1024 ** 7 Yi = 1024 ** 8 #Decimal unit constants. k = 1000 M = 1000 ** 2 G = 1000 ** 3 T = 1000 ** 4 P = 1000 ** 5 E = 1000 ** 6 Z = 1000 ** 7 Y = 1000 ** 8 glance-2014.1/glance/openstack/common/threadgroup.py0000664000175400017540000000667212323736226023617 0ustar jenkinsjenkins00000000000000# vim: tabstop=4 shiftwidth=4 softtabstop=4 # Copyright 2012 Red Hat, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from eventlet import greenlet from eventlet import greenpool from eventlet import greenthread from glance.openstack.common import log as logging from glance.openstack.common import loopingcall LOG = logging.getLogger(__name__) def _thread_done(gt, *args, **kwargs): """ Callback function to be passed to GreenThread.link() when we spawn() Calls the :class:`ThreadGroup` to notify if. """ kwargs['group'].thread_done(kwargs['thread']) class Thread(object): """ Wrapper around a greenthread, that holds a reference to the :class:`ThreadGroup`. The Thread will notify the :class:`ThreadGroup` when it has done so it can be removed from the threads list. """ def __init__(self, thread, group): self.thread = thread self.thread.link(_thread_done, group=group, thread=self) def stop(self): self.thread.kill() def wait(self): return self.thread.wait() class ThreadGroup(object): """ The point of the ThreadGroup classis to: * keep track of timers and greenthreads (making it easier to stop them when need be). * provide an easy API to add timers. """ def __init__(self, thread_pool_size=10): self.pool = greenpool.GreenPool(thread_pool_size) self.threads = [] self.timers = [] def add_timer(self, interval, callback, initial_delay=None, *args, **kwargs): pulse = loopingcall.FixedIntervalLoopingCall(callback, *args, **kwargs) pulse.start(interval=interval, initial_delay=initial_delay) self.timers.append(pulse) def add_thread(self, callback, *args, **kwargs): gt = self.pool.spawn(callback, *args, **kwargs) th = Thread(gt, self) self.threads.append(th) def thread_done(self, thread): self.threads.remove(thread) def stop(self): current = greenthread.getcurrent() for x in self.threads: if x is current: # don't kill the current thread. continue try: x.stop() except Exception as ex: LOG.exception(ex) for x in self.timers: try: x.stop() except Exception as ex: LOG.exception(ex) self.timers = [] def wait(self): for x in self.timers: try: x.wait() except greenlet.GreenletExit: pass except Exception as ex: LOG.exception(ex) current = greenthread.getcurrent() for x in self.threads: if x is current: continue try: x.wait() except greenlet.GreenletExit: pass except Exception as ex: LOG.exception(ex) glance-2014.1/glance/openstack/common/eventlet_backdoor.py0000664000175400017540000000515512323736226024760 0ustar jenkinsjenkins00000000000000# vim: tabstop=4 shiftwidth=4 softtabstop=4 # Copyright (c) 2012 OpenStack Foundation. # Administrator of the National Aeronautics and Space Administration. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from __future__ import print_function import gc import pprint import sys import traceback import eventlet import eventlet.backdoor import greenlet from oslo.config import cfg eventlet_backdoor_opts = [ cfg.IntOpt('backdoor_port', default=None, help='port for eventlet backdoor to listen') ] CONF = cfg.CONF CONF.register_opts(eventlet_backdoor_opts) def _dont_use_this(): print("Don't use this, just disconnect instead") def _find_objects(t): return filter(lambda o: isinstance(o, t), gc.get_objects()) def _print_greenthreads(): for i, gt in enumerate(_find_objects(greenlet.greenlet)): print(i, gt) traceback.print_stack(gt.gr_frame) print() def _print_nativethreads(): for threadId, stack in sys._current_frames().items(): print(threadId) traceback.print_stack(stack) print() def initialize_if_enabled(): backdoor_locals = { 'exit': _dont_use_this, # So we don't exit the entire process 'quit': _dont_use_this, # So we don't exit the entire process 'fo': _find_objects, 'pgt': _print_greenthreads, 'pnt': _print_nativethreads, } if CONF.backdoor_port is None: return None # NOTE(johannes): The standard sys.displayhook will print the value of # the last expression and set it to __builtin__._, which overwrites # the __builtin__._ that gettext sets. Let's switch to using pprint # since it won't interact poorly with gettext, and it's easier to # read the output too. def displayhook(val): if val is not None: pprint.pprint(val) sys.displayhook = displayhook sock = eventlet.listen(('localhost', CONF.backdoor_port)) port = sock.getsockname()[1] eventlet.spawn_n(eventlet.backdoor.backdoor_server, sock, locals=backdoor_locals) return port glance-2014.1/glance/openstack/common/importutils.py0000664000175400017540000000421512323736226023655 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ Import related utilities and helper functions. """ import sys import traceback def import_class(import_str): """Returns a class from a string including module and class.""" mod_str, _sep, class_str = import_str.rpartition('.') try: __import__(mod_str) return getattr(sys.modules[mod_str], class_str) except (ValueError, AttributeError): raise ImportError('Class %s cannot be found (%s)' % (class_str, traceback.format_exception(*sys.exc_info()))) def import_object(import_str, *args, **kwargs): """Import a class and return an instance of it.""" return import_class(import_str)(*args, **kwargs) def import_object_ns(name_space, import_str, *args, **kwargs): """Tries to import object from default namespace. Imports a class and return an instance of it, first by trying to find the class in a default namespace, then failing back to a full path if not found in the default namespace. """ import_value = "%s.%s" % (name_space, import_str) try: return import_class(import_value)(*args, **kwargs) except ImportError: return import_class(import_str)(*args, **kwargs) def import_module(import_str): """Import a module.""" __import__(import_str) return sys.modules[import_str] def try_import(import_str, default=None): """Try to import a module and if it fails return default.""" try: return import_module(import_str) except ImportError: return default glance-2014.1/glance/openstack/common/strutils.py0000664000175400017540000001652412323736226023161 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ System-level utilities and helper functions. """ import re import sys import unicodedata import six from glance.openstack.common.gettextutils import _ # Used for looking up extensions of text # to their 'multiplied' byte amount BYTE_MULTIPLIERS = { '': 1, 't': 1024 ** 4, 'g': 1024 ** 3, 'm': 1024 ** 2, 'k': 1024, } BYTE_REGEX = re.compile(r'(^-?\d+)(\D*)') TRUE_STRINGS = ('1', 't', 'true', 'on', 'y', 'yes') FALSE_STRINGS = ('0', 'f', 'false', 'off', 'n', 'no') SLUGIFY_STRIP_RE = re.compile(r"[^\w\s-]") SLUGIFY_HYPHENATE_RE = re.compile(r"[-\s]+") def int_from_bool_as_string(subject): """Interpret a string as a boolean and return either 1 or 0. Any string value in: ('True', 'true', 'On', 'on', '1') is interpreted as a boolean True. Useful for JSON-decoded stuff and config file parsing """ return bool_from_string(subject) and 1 or 0 def bool_from_string(subject, strict=False): """Interpret a string as a boolean. A case-insensitive match is performed such that strings matching 't', 'true', 'on', 'y', 'yes', or '1' are considered True and, when `strict=False`, anything else is considered False. Useful for JSON-decoded stuff and config file parsing. If `strict=True`, unrecognized values, including None, will raise a ValueError which is useful when parsing values passed in from an API call. Strings yielding False are 'f', 'false', 'off', 'n', 'no', or '0'. """ if not isinstance(subject, six.string_types): subject = str(subject) lowered = subject.strip().lower() if lowered in TRUE_STRINGS: return True elif lowered in FALSE_STRINGS: return False elif strict: acceptable = ', '.join( "'%s'" % s for s in sorted(TRUE_STRINGS + FALSE_STRINGS)) msg = _("Unrecognized value '%(val)s', acceptable values are:" " %(acceptable)s") % {'val': subject, 'acceptable': acceptable} raise ValueError(msg) else: return False def safe_decode(text, incoming=None, errors='strict'): """Decodes incoming str using `incoming` if they're not already unicode. :param incoming: Text's current encoding :param errors: Errors handling policy. See here for valid values http://docs.python.org/2/library/codecs.html :returns: text or a unicode `incoming` encoded representation of it. :raises TypeError: If text is not an instance of str """ if not isinstance(text, six.string_types): raise TypeError("%s can't be decoded" % type(text)) if isinstance(text, six.text_type): return text if not incoming: incoming = (sys.stdin.encoding or sys.getdefaultencoding()) try: return text.decode(incoming, errors) except UnicodeDecodeError: # Note(flaper87) If we get here, it means that # sys.stdin.encoding / sys.getdefaultencoding # didn't return a suitable encoding to decode # text. This happens mostly when global LANG # var is not set correctly and there's no # default encoding. In this case, most likely # python will use ASCII or ANSI encoders as # default encodings but they won't be capable # of decoding non-ASCII characters. # # Also, UTF-8 is being used since it's an ASCII # extension. return text.decode('utf-8', errors) def safe_encode(text, incoming=None, encoding='utf-8', errors='strict'): """Encodes incoming str/unicode using `encoding`. If incoming is not specified, text is expected to be encoded with current python's default encoding. (`sys.getdefaultencoding`) :param incoming: Text's current encoding :param encoding: Expected encoding for text (Default UTF-8) :param errors: Errors handling policy. See here for valid values http://docs.python.org/2/library/codecs.html :returns: text or a bytestring `encoding` encoded representation of it. :raises TypeError: If text is not an instance of str """ if not isinstance(text, six.string_types): raise TypeError("%s can't be encoded" % type(text)) if not incoming: incoming = (sys.stdin.encoding or sys.getdefaultencoding()) if isinstance(text, six.text_type): if six.PY3: return text.encode(encoding, errors).decode(incoming) else: return text.encode(encoding, errors) elif text and encoding != incoming: # Decode text before encoding it with `encoding` text = safe_decode(text, incoming, errors) if six.PY3: return text.encode(encoding, errors).decode(incoming) else: return text.encode(encoding, errors) return text def to_bytes(text, default=0): """Converts a string into an integer of bytes. Looks at the last characters of the text to determine what conversion is needed to turn the input text into a byte number. Supports "B, K(B), M(B), G(B), and T(B)". (case insensitive) :param text: String input for bytes size conversion. :param default: Default return value when text is blank. """ match = BYTE_REGEX.search(text) if match: magnitude = int(match.group(1)) mult_key_org = match.group(2) if not mult_key_org: return magnitude elif text: msg = _('Invalid string format: %s') % text raise TypeError(msg) else: return default mult_key = mult_key_org.lower().replace('b', '', 1) multiplier = BYTE_MULTIPLIERS.get(mult_key) if multiplier is None: msg = _('Unknown byte multiplier: %s') % mult_key_org raise TypeError(msg) return magnitude * multiplier def to_slug(value, incoming=None, errors="strict"): """Normalize string. Convert to lowercase, remove non-word characters, and convert spaces to hyphens. Inspired by Django's `slugify` filter. :param value: Text to slugify :param incoming: Text's current encoding :param errors: Errors handling policy. See here for valid values http://docs.python.org/2/library/codecs.html :returns: slugified unicode representation of `value` :raises TypeError: If text is not an instance of str """ value = safe_decode(value, incoming, errors) # NOTE(aababilov): no need to use safe_(encode|decode) here: # encodings are always "ascii", error handling is always "ignore" # and types are always known (first: unicode; second: str) value = unicodedata.normalize("NFKD", value).encode( "ascii", "ignore").decode("ascii") value = SLUGIFY_STRIP_RE.sub("", value).strip().lower() return SLUGIFY_HYPHENATE_RE.sub("-", value) glance-2014.1/glance/openstack/common/lockutils.py0000664000175400017540000002331712323736226023277 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import contextlib import errno import functools import os import shutil import subprocess import sys import tempfile import threading import time import weakref from oslo.config import cfg from glance.openstack.common import fileutils from glance.openstack.common.gettextutils import _ from glance.openstack.common import local from glance.openstack.common import log as logging LOG = logging.getLogger(__name__) util_opts = [ cfg.BoolOpt('disable_process_locking', default=False, help='Whether to disable inter-process locks'), cfg.StrOpt('lock_path', default=os.environ.get("GLANCE_LOCK_PATH"), help=('Directory to use for lock files.')) ] CONF = cfg.CONF CONF.register_opts(util_opts) def set_defaults(lock_path): cfg.set_defaults(util_opts, lock_path=lock_path) class _InterProcessLock(object): """Lock implementation which allows multiple locks, working around issues like bugs.debian.org/cgi-bin/bugreport.cgi?bug=632857 and does not require any cleanup. Since the lock is always held on a file descriptor rather than outside of the process, the lock gets dropped automatically if the process crashes, even if __exit__ is not executed. There are no guarantees regarding usage by multiple green threads in a single process here. This lock works only between processes. Exclusive access between local threads should be achieved using the semaphores in the @synchronized decorator. Note these locks are released when the descriptor is closed, so it's not safe to close the file descriptor while another green thread holds the lock. Just opening and closing the lock file can break synchronisation, so lock files must be accessed only using this abstraction. """ def __init__(self, name): self.lockfile = None self.fname = name def __enter__(self): self.lockfile = open(self.fname, 'w') while True: try: # Using non-blocking locks since green threads are not # patched to deal with blocking locking calls. # Also upon reading the MSDN docs for locking(), it seems # to have a laughable 10 attempts "blocking" mechanism. self.trylock() return self except IOError as e: if e.errno in (errno.EACCES, errno.EAGAIN): # external locks synchronise things like iptables # updates - give it some time to prevent busy spinning time.sleep(0.01) else: raise def __exit__(self, exc_type, exc_val, exc_tb): try: self.unlock() self.lockfile.close() except IOError: LOG.exception(_("Could not release the acquired lock `%s`"), self.fname) def trylock(self): raise NotImplementedError() def unlock(self): raise NotImplementedError() class _WindowsLock(_InterProcessLock): def trylock(self): msvcrt.locking(self.lockfile.fileno(), msvcrt.LK_NBLCK, 1) def unlock(self): msvcrt.locking(self.lockfile.fileno(), msvcrt.LK_UNLCK, 1) class _PosixLock(_InterProcessLock): def trylock(self): fcntl.lockf(self.lockfile, fcntl.LOCK_EX | fcntl.LOCK_NB) def unlock(self): fcntl.lockf(self.lockfile, fcntl.LOCK_UN) if os.name == 'nt': import msvcrt InterProcessLock = _WindowsLock else: import fcntl InterProcessLock = _PosixLock _semaphores = weakref.WeakValueDictionary() _semaphores_lock = threading.Lock() @contextlib.contextmanager def lock(name, lock_file_prefix=None, external=False, lock_path=None): """Context based lock This function yields a `threading.Semaphore` instance (if we don't use eventlet.monkey_patch(), else `semaphore.Semaphore`) unless external is True, in which case, it'll yield an InterProcessLock instance. :param lock_file_prefix: The lock_file_prefix argument is used to provide lock files on disk with a meaningful prefix. :param external: The external keyword argument denotes whether this lock should work across multiple processes. This means that if two different workers both run a a method decorated with @synchronized('mylock', external=True), only one of them will execute at a time. :param lock_path: The lock_path keyword argument is used to specify a special location for external lock files to live. If nothing is set, then CONF.lock_path is used as a default. """ with _semaphores_lock: try: sem = _semaphores[name] except KeyError: sem = threading.Semaphore() _semaphores[name] = sem with sem: LOG.debug(_('Got semaphore "%(lock)s"'), {'lock': name}) # NOTE(mikal): I know this looks odd if not hasattr(local.strong_store, 'locks_held'): local.strong_store.locks_held = [] local.strong_store.locks_held.append(name) try: if external and not CONF.disable_process_locking: LOG.debug(_('Attempting to grab file lock "%(lock)s"'), {'lock': name}) # We need a copy of lock_path because it is non-local local_lock_path = lock_path or CONF.lock_path if not local_lock_path: raise cfg.RequiredOptError('lock_path') if not os.path.exists(local_lock_path): fileutils.ensure_tree(local_lock_path) LOG.info(_('Created lock path: %s'), local_lock_path) def add_prefix(name, prefix): if not prefix: return name sep = '' if prefix.endswith('-') else '-' return '%s%s%s' % (prefix, sep, name) # NOTE(mikal): the lock name cannot contain directory # separators lock_file_name = add_prefix(name.replace(os.sep, '_'), lock_file_prefix) lock_file_path = os.path.join(local_lock_path, lock_file_name) try: lock = InterProcessLock(lock_file_path) with lock as lock: LOG.debug(_('Got file lock "%(lock)s" at %(path)s'), {'lock': name, 'path': lock_file_path}) yield lock finally: LOG.debug(_('Released file lock "%(lock)s" at %(path)s'), {'lock': name, 'path': lock_file_path}) else: yield sem finally: local.strong_store.locks_held.remove(name) def synchronized(name, lock_file_prefix=None, external=False, lock_path=None): """Synchronization decorator. Decorating a method like so:: @synchronized('mylock') def foo(self, *args): ... ensures that only one thread will execute the foo method at a time. Different methods can share the same lock:: @synchronized('mylock') def foo(self, *args): ... @synchronized('mylock') def bar(self, *args): ... This way only one of either foo or bar can be executing at a time. """ def wrap(f): @functools.wraps(f) def inner(*args, **kwargs): try: with lock(name, lock_file_prefix, external, lock_path): LOG.debug(_('Got semaphore / lock "%(function)s"'), {'function': f.__name__}) return f(*args, **kwargs) finally: LOG.debug(_('Semaphore / lock released "%(function)s"'), {'function': f.__name__}) return inner return wrap def synchronized_with_prefix(lock_file_prefix): """Partial object generator for the synchronization decorator. Redefine @synchronized in each project like so:: (in nova/utils.py) from nova.openstack.common import lockutils synchronized = lockutils.synchronized_with_prefix('nova-') (in nova/foo.py) from nova import utils @utils.synchronized('mylock') def bar(self, *args): ... The lock_file_prefix argument is used to provide lock files on disk with a meaningful prefix. """ return functools.partial(synchronized, lock_file_prefix=lock_file_prefix) def main(argv): """Create a dir for locks and pass it to command from arguments If you run this: python -m openstack.common.lockutils python setup.py testr a temporary directory will be created for all your locks and passed to all your tests in an environment variable. The temporary dir will be deleted afterwards and the return value will be preserved. """ lock_dir = tempfile.mkdtemp() os.environ["GLANCE_LOCK_PATH"] = lock_dir try: ret_val = subprocess.call(argv[1:]) finally: shutil.rmtree(lock_dir, ignore_errors=True) return ret_val if __name__ == '__main__': sys.exit(main(sys.argv)) glance-2014.1/glance/openstack/common/loopingcall.py0000664000175400017540000001107112323736226023563 0ustar jenkinsjenkins00000000000000# vim: tabstop=4 shiftwidth=4 softtabstop=4 # Copyright 2010 United States Government as represented by the # Administrator of the National Aeronautics and Space Administration. # Copyright 2011 Justin Santa Barbara # 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 sys from eventlet import event from eventlet import greenthread from glance.openstack.common.gettextutils import _ from glance.openstack.common import log as logging from glance.openstack.common import timeutils LOG = logging.getLogger(__name__) class LoopingCallDone(Exception): """Exception to break out and stop a LoopingCall. The poll-function passed to LoopingCall can raise this exception to break out of the loop normally. This is somewhat analogous to StopIteration. An optional return-value can be included as the argument to the exception; this return-value will be returned by LoopingCall.wait() """ def __init__(self, retvalue=True): """:param retvalue: Value that LoopingCall.wait() should return.""" self.retvalue = retvalue class LoopingCallBase(object): def __init__(self, f=None, *args, **kw): self.args = args self.kw = kw self.f = f self._running = False self.done = None def stop(self): self._running = False def wait(self): return self.done.wait() class FixedIntervalLoopingCall(LoopingCallBase): """A fixed interval looping call.""" def start(self, interval, initial_delay=None): self._running = True done = event.Event() def _inner(): if initial_delay: greenthread.sleep(initial_delay) try: while self._running: start = timeutils.utcnow() self.f(*self.args, **self.kw) end = timeutils.utcnow() if not self._running: break delay = interval - timeutils.delta_seconds(start, end) if delay <= 0: LOG.warn(_('task run outlasted interval by %s sec') % -delay) greenthread.sleep(delay if delay > 0 else 0) except LoopingCallDone as e: self.stop() done.send(e.retvalue) except Exception: LOG.exception(_('in fixed duration looping call')) done.send_exception(*sys.exc_info()) return else: done.send(True) self.done = done greenthread.spawn_n(_inner) return self.done # TODO(mikal): this class name is deprecated in Havana and should be removed # in the I release LoopingCall = FixedIntervalLoopingCall class DynamicLoopingCall(LoopingCallBase): """A looping call which sleeps until the next known event. The function called should return how long to sleep for before being called again. """ def start(self, initial_delay=None, periodic_interval_max=None): self._running = True done = event.Event() def _inner(): if initial_delay: greenthread.sleep(initial_delay) try: while self._running: idle = self.f(*self.args, **self.kw) if not self._running: break if periodic_interval_max is not None: idle = min(idle, periodic_interval_max) LOG.debug(_('Dynamic looping call sleeping for %.02f ' 'seconds'), idle) greenthread.sleep(idle) except LoopingCallDone as e: self.stop() done.send(e.retvalue) except Exception: LOG.exception(_('in dynamic looping call')) done.send_exception(*sys.exc_info()) return else: done.send(True) self.done = done greenthread.spawn(_inner) return self.done glance-2014.1/glance/openstack/common/README0000664000175400017540000000072312323736226021570 0ustar jenkinsjenkins00000000000000openstack-common ---------------- A number of modules from openstack-common are imported into this project. These modules are "incubating" in openstack-common and are kept in sync with the help of openstack-common's update.py script. See: https://wiki.openstack.org/wiki/Oslo#Syncing_Code_from_Incubator The copy of the code should never be directly modified here. Please always update openstack-common first and then run the script to copy the changes across. glance-2014.1/glance/openstack/common/timeutils.py0000664000175400017540000001424012323736226023300 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ Time related utilities and helper functions. """ import calendar import datetime import time import iso8601 import six # ISO 8601 extended time format with microseconds _ISO8601_TIME_FORMAT_SUBSECOND = '%Y-%m-%dT%H:%M:%S.%f' _ISO8601_TIME_FORMAT = '%Y-%m-%dT%H:%M:%S' PERFECT_TIME_FORMAT = _ISO8601_TIME_FORMAT_SUBSECOND def isotime(at=None, subsecond=False): """Stringify time in ISO 8601 format.""" if not at: at = utcnow() st = at.strftime(_ISO8601_TIME_FORMAT if not subsecond else _ISO8601_TIME_FORMAT_SUBSECOND) tz = at.tzinfo.tzname(None) if at.tzinfo else 'UTC' st += ('Z' if tz == 'UTC' else tz) return st def parse_isotime(timestr): """Parse time from ISO 8601 format.""" try: return iso8601.parse_date(timestr) except iso8601.ParseError as e: raise ValueError(six.text_type(e)) except TypeError as e: raise ValueError(six.text_type(e)) def strtime(at=None, fmt=PERFECT_TIME_FORMAT): """Returns formatted utcnow.""" if not at: at = utcnow() return at.strftime(fmt) def parse_strtime(timestr, fmt=PERFECT_TIME_FORMAT): """Turn a formatted time back into a datetime.""" return datetime.datetime.strptime(timestr, fmt) def normalize_time(timestamp): """Normalize time in arbitrary timezone to UTC naive object.""" offset = timestamp.utcoffset() if offset is None: return timestamp return timestamp.replace(tzinfo=None) - offset def is_older_than(before, seconds): """Return True if before is older than seconds.""" if isinstance(before, six.string_types): before = parse_strtime(before).replace(tzinfo=None) else: before = before.replace(tzinfo=None) return utcnow() - before > datetime.timedelta(seconds=seconds) def is_newer_than(after, seconds): """Return True if after is newer than seconds.""" if isinstance(after, six.string_types): after = parse_strtime(after).replace(tzinfo=None) else: after = after.replace(tzinfo=None) return after - utcnow() > datetime.timedelta(seconds=seconds) def utcnow_ts(): """Timestamp version of our utcnow function.""" if utcnow.override_time is None: # NOTE(kgriffs): This is several times faster # than going through calendar.timegm(...) return int(time.time()) return calendar.timegm(utcnow().timetuple()) def utcnow(): """Overridable version of utils.utcnow.""" if utcnow.override_time: try: return utcnow.override_time.pop(0) except AttributeError: return utcnow.override_time return datetime.datetime.utcnow() def iso8601_from_timestamp(timestamp): """Returns a iso8601 formated date from timestamp.""" return isotime(datetime.datetime.utcfromtimestamp(timestamp)) utcnow.override_time = None def set_time_override(override_time=None): """Overrides utils.utcnow. Make it return a constant time or a list thereof, one at a time. :param override_time: datetime instance or list thereof. If not given, defaults to the current UTC time. """ utcnow.override_time = override_time or datetime.datetime.utcnow() def advance_time_delta(timedelta): """Advance overridden time using a datetime.timedelta.""" assert(not utcnow.override_time is None) try: for dt in utcnow.override_time: dt += timedelta except TypeError: utcnow.override_time += timedelta def advance_time_seconds(seconds): """Advance overridden time by seconds.""" advance_time_delta(datetime.timedelta(0, seconds)) def clear_time_override(): """Remove the overridden time.""" utcnow.override_time = None def marshall_now(now=None): """Make an rpc-safe datetime with microseconds. Note: tzinfo is stripped, but not required for relative times. """ if not now: now = utcnow() return dict(day=now.day, month=now.month, year=now.year, hour=now.hour, minute=now.minute, second=now.second, microsecond=now.microsecond) def unmarshall_time(tyme): """Unmarshall a datetime dict.""" return datetime.datetime(day=tyme['day'], month=tyme['month'], year=tyme['year'], hour=tyme['hour'], minute=tyme['minute'], second=tyme['second'], microsecond=tyme['microsecond']) def delta_seconds(before, after): """Return the difference between two timing objects. Compute the difference in seconds between two date, time, or datetime objects (as a float, to microsecond resolution). """ delta = after - before return total_seconds(delta) def total_seconds(delta): """Return the total seconds of datetime.timedelta object. Compute total seconds of datetime.timedelta, datetime.timedelta doesn't have method total_seconds in Python2.6, calculate it manually. """ try: return delta.total_seconds() except AttributeError: return ((delta.days * 24 * 3600) + delta.seconds + float(delta.microseconds) / (10 ** 6)) def is_soon(dt, window): """Determines if time is going to happen in the next window seconds. :param dt: the time :param window: minimum seconds to remain to consider the time not soon :return: True if expiration is within the given duration """ soon = (utcnow() + datetime.timedelta(seconds=window)) return normalize_time(dt) <= soon glance-2014.1/glance/openstack/common/policy.py0000664000175400017540000005215712323736226022571 0ustar jenkinsjenkins00000000000000# vim: tabstop=4 shiftwidth=4 softtabstop=4 # Copyright (c) 2012 OpenStack Foundation. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ Common Policy Engine Implementation Policies can be expressed in one of two forms: A list of lists, or a string written in the new policy language. In the list-of-lists representation, each check inside the innermost list is combined as with an "and" conjunction--for that check to pass, all the specified checks must pass. These innermost lists are then combined as with an "or" conjunction. This is the original way of expressing policies, but there now exists a new way: the policy language. In the policy language, each check is specified the same way as in the list-of-lists representation: a simple "a:b" pair that is matched to the correct code to perform that check. However, conjunction operators are available, allowing for more expressiveness in crafting policies. As an example, take the following rule, expressed in the list-of-lists representation:: [["role:admin"], ["project_id:%(project_id)s", "role:projectadmin"]] In the policy language, this becomes:: role:admin or (project_id:%(project_id)s and role:projectadmin) The policy language also has the "not" operator, allowing a richer policy rule:: project_id:%(project_id)s and not role:dunce Finally, two special policy checks should be mentioned; the policy check "@" will always accept an access, and the policy check "!" will always reject an access. (Note that if a rule is either the empty list ("[]") or the empty string, this is equivalent to the "@" policy check.) Of these, the "!" policy check is probably the most useful, as it allows particular rules to be explicitly disabled. """ import abc import re import urllib import six import urllib2 from glance.openstack.common.gettextutils import _ from glance.openstack.common import jsonutils from glance.openstack.common import log as logging LOG = logging.getLogger(__name__) _rules = None _checks = {} class Rules(dict): """ A store for rules. Handles the default_rule setting directly. """ @classmethod def load_json(cls, data, default_rule=None): """ Allow loading of JSON rule data. """ # Suck in the JSON data and parse the rules rules = dict((k, parse_rule(v)) for k, v in jsonutils.loads(data).items()) return cls(rules, default_rule) def __init__(self, rules=None, default_rule=None): """Initialize the Rules store.""" super(Rules, self).__init__(rules or {}) self.default_rule = default_rule def __missing__(self, key): """Implements the default rule handling.""" # If the default rule isn't actually defined, do something # reasonably intelligent if not self.default_rule or self.default_rule not in self: raise KeyError(key) return self[self.default_rule] def __str__(self): """Dumps a string representation of the rules.""" # Start by building the canonical strings for the rules out_rules = {} for key, value in self.items(): # Use empty string for singleton TrueCheck instances if isinstance(value, TrueCheck): out_rules[key] = '' else: out_rules[key] = str(value) # Dump a pretty-printed JSON representation return jsonutils.dumps(out_rules, indent=4) # Really have to figure out a way to deprecate this def set_rules(rules): """Set the rules in use for policy checks.""" global _rules _rules = rules # Ditto def reset(): """Clear the rules used for policy checks.""" global _rules _rules = None def check(rule, target, creds, exc=None, *args, **kwargs): """ Checks authorization of a rule against the target and credentials. :param rule: The rule to evaluate. :param target: As much information about the object being operated on as possible, as a dictionary. :param creds: As much information about the user performing the action as possible, as a dictionary. :param exc: Class of the exception to raise if the check fails. Any remaining arguments passed to check() (both positional and keyword arguments) will be passed to the exception class. If exc is not provided, returns False. :return: Returns False if the policy does not allow the action and exc is not provided; otherwise, returns a value that evaluates to True. Note: for rules using the "case" expression, this True value will be the specified string from the expression. """ # Allow the rule to be a Check tree if isinstance(rule, BaseCheck): result = rule(target, creds) elif not _rules: # No rules to reference means we're going to fail closed result = False else: try: # Evaluate the rule result = _rules[rule](target, creds) except KeyError: # If the rule doesn't exist, fail closed result = False # If it is False, raise the exception if requested if exc and result is False: raise exc(*args, **kwargs) return result class BaseCheck(object): """ Abstract base class for Check classes. """ __metaclass__ = abc.ABCMeta @abc.abstractmethod def __str__(self): """ Retrieve a string representation of the Check tree rooted at this node. """ pass @abc.abstractmethod def __call__(self, target, cred): """ Perform the check. Returns False to reject the access or a true value (not necessary True) to accept the access. """ pass class FalseCheck(BaseCheck): """ A policy check that always returns False (disallow). """ def __str__(self): """Return a string representation of this check.""" return "!" def __call__(self, target, cred): """Check the policy.""" return False class TrueCheck(BaseCheck): """ A policy check that always returns True (allow). """ def __str__(self): """Return a string representation of this check.""" return "@" def __call__(self, target, cred): """Check the policy.""" return True class Check(BaseCheck): """ A base class to allow for user-defined policy checks. """ def __init__(self, kind, match): """ :param kind: The kind of the check, i.e., the field before the ':'. :param match: The match of the check, i.e., the field after the ':'. """ self.kind = kind self.match = match def __str__(self): """Return a string representation of this check.""" return "%s:%s" % (self.kind, self.match) class NotCheck(BaseCheck): """ A policy check that inverts the result of another policy check. Implements the "not" operator. """ def __init__(self, rule): """ Initialize the 'not' check. :param rule: The rule to negate. Must be a Check. """ self.rule = rule def __str__(self): """Return a string representation of this check.""" return "not %s" % self.rule def __call__(self, target, cred): """ Check the policy. Returns the logical inverse of the wrapped check. """ return not self.rule(target, cred) class AndCheck(BaseCheck): """ A policy check that requires that a list of other checks all return True. Implements the "and" operator. """ def __init__(self, rules): """ Initialize the 'and' check. :param rules: A list of rules that will be tested. """ self.rules = rules def __str__(self): """Return a string representation of this check.""" return "(%s)" % ' and '.join(str(r) for r in self.rules) def __call__(self, target, cred): """ Check the policy. Requires that all rules accept in order to return True. """ for rule in self.rules: if not rule(target, cred): return False return True def add_check(self, rule): """ Allows addition of another rule to the list of rules that will be tested. Returns the AndCheck object for convenience. """ self.rules.append(rule) return self class OrCheck(BaseCheck): """ A policy check that requires that at least one of a list of other checks returns True. Implements the "or" operator. """ def __init__(self, rules): """ Initialize the 'or' check. :param rules: A list of rules that will be tested. """ self.rules = rules def __str__(self): """Return a string representation of this check.""" return "(%s)" % ' or '.join(str(r) for r in self.rules) def __call__(self, target, cred): """ Check the policy. Requires that at least one rule accept in order to return True. """ for rule in self.rules: if rule(target, cred): return True return False def add_check(self, rule): """ Allows addition of another rule to the list of rules that will be tested. Returns the OrCheck object for convenience. """ self.rules.append(rule) return self def _parse_check(rule): """ Parse a single base check rule into an appropriate Check object. """ # Handle the special checks if rule == '!': return FalseCheck() elif rule == '@': return TrueCheck() try: kind, match = rule.split(':', 1) except Exception: LOG.exception(_("Failed to understand rule %(rule)s") % locals()) # If the rule is invalid, we'll fail closed return FalseCheck() # Find what implements the check if kind in _checks: return _checks[kind](kind, match) elif None in _checks: return _checks[None](kind, match) else: LOG.error(_("No handler for matches of kind %s") % kind) return FalseCheck() def _parse_list_rule(rule): """ Provided for backwards compatibility. Translates the old list-of-lists syntax into a tree of Check objects. """ # Empty rule defaults to True if not rule: return TrueCheck() # Outer list is joined by "or"; inner list by "and" or_list = [] for inner_rule in rule: # Elide empty inner lists if not inner_rule: continue # Handle bare strings if isinstance(inner_rule, basestring): inner_rule = [inner_rule] # Parse the inner rules into Check objects and_list = [_parse_check(r) for r in inner_rule] # Append the appropriate check to the or_list if len(and_list) == 1: or_list.append(and_list[0]) else: or_list.append(AndCheck(and_list)) # If we have only one check, omit the "or" if not or_list: return FalseCheck() elif len(or_list) == 1: return or_list[0] return OrCheck(or_list) # Used for tokenizing the policy language _tokenize_re = re.compile(r'\s+') def _parse_tokenize(rule): """ Tokenizer for the policy language. Most of the single-character tokens are specified in the _tokenize_re; however, parentheses need to be handled specially, because they can appear inside a check string. Thankfully, those parentheses that appear inside a check string can never occur at the very beginning or end ("%(variable)s" is the correct syntax). """ for tok in _tokenize_re.split(rule): # Skip empty tokens if not tok or tok.isspace(): continue # Handle leading parens on the token clean = tok.lstrip('(') for i in range(len(tok) - len(clean)): yield '(', '(' # If it was only parentheses, continue if not clean: continue else: tok = clean # Handle trailing parens on the token clean = tok.rstrip(')') trail = len(tok) - len(clean) # Yield the cleaned token lowered = clean.lower() if lowered in ('and', 'or', 'not'): # Special tokens yield lowered, clean elif clean: # Not a special token, but not composed solely of ')' if len(tok) >= 2 and ((tok[0], tok[-1]) in [('"', '"'), ("'", "'")]): # It's a quoted string yield 'string', tok[1:-1] else: yield 'check', _parse_check(clean) # Yield the trailing parens for i in range(trail): yield ')', ')' class ParseStateMeta(type): """ Metaclass for the ParseState class. Facilitates identifying reduction methods. """ def __new__(mcs, name, bases, cls_dict): """ Create the class. Injects the 'reducers' list, a list of tuples matching token sequences to the names of the corresponding reduction methods. """ reducers = [] for key, value in cls_dict.items(): if not hasattr(value, 'reducers'): continue for reduction in value.reducers: reducers.append((reduction, key)) cls_dict['reducers'] = reducers return super(ParseStateMeta, mcs).__new__(mcs, name, bases, cls_dict) def reducer(*tokens): """ Decorator for reduction methods. Arguments are a sequence of tokens, in order, which should trigger running this reduction method. """ def decorator(func): # Make sure we have a list of reducer sequences if not hasattr(func, 'reducers'): func.reducers = [] # Add the tokens to the list of reducer sequences func.reducers.append(list(tokens)) return func return decorator class ParseState(object): """ Implement the core of parsing the policy language. Uses a greedy reduction algorithm to reduce a sequence of tokens into a single terminal, the value of which will be the root of the Check tree. Note: error reporting is rather lacking. The best we can get with this parser formulation is an overall "parse failed" error. Fortunately, the policy language is simple enough that this shouldn't be that big a problem. """ __metaclass__ = ParseStateMeta def __init__(self): """Initialize the ParseState.""" self.tokens = [] self.values = [] def reduce(self): """ Perform a greedy reduction of the token stream. If a reducer method matches, it will be executed, then the reduce() method will be called recursively to search for any more possible reductions. """ for reduction, methname in self.reducers: if (len(self.tokens) >= len(reduction) and self.tokens[-len(reduction):] == reduction): # Get the reduction method meth = getattr(self, methname) # Reduce the token stream results = meth(*self.values[-len(reduction):]) # Update the tokens and values self.tokens[-len(reduction):] = [r[0] for r in results] self.values[-len(reduction):] = [r[1] for r in results] # Check for any more reductions return self.reduce() def shift(self, tok, value): """Adds one more token to the state. Calls reduce().""" self.tokens.append(tok) self.values.append(value) # Do a greedy reduce... self.reduce() @property def result(self): """ Obtain the final result of the parse. Raises ValueError if the parse failed to reduce to a single result. """ if len(self.values) != 1: raise ValueError("Could not parse rule") return self.values[0] @reducer('(', 'check', ')') @reducer('(', 'and_expr', ')') @reducer('(', 'or_expr', ')') def _wrap_check(self, _p1, check, _p2): """Turn parenthesized expressions into a 'check' token.""" return [('check', check)] @reducer('check', 'and', 'check') def _make_and_expr(self, check1, _and, check2): """ Create an 'and_expr' from two checks joined by the 'and' operator. """ return [('and_expr', AndCheck([check1, check2]))] @reducer('and_expr', 'and', 'check') def _extend_and_expr(self, and_expr, _and, check): """ Extend an 'and_expr' by adding one more check. """ return [('and_expr', and_expr.add_check(check))] @reducer('check', 'or', 'check') def _make_or_expr(self, check1, _or, check2): """ Create an 'or_expr' from two checks joined by the 'or' operator. """ return [('or_expr', OrCheck([check1, check2]))] @reducer('or_expr', 'or', 'check') def _extend_or_expr(self, or_expr, _or, check): """ Extend an 'or_expr' by adding one more check. """ return [('or_expr', or_expr.add_check(check))] @reducer('not', 'check') def _make_not_expr(self, _not, check): """Invert the result of another check.""" return [('check', NotCheck(check))] def _parse_text_rule(rule): """ Translates a policy written in the policy language into a tree of Check objects. """ # Empty rule means always accept if not rule: return TrueCheck() # Parse the token stream state = ParseState() for tok, value in _parse_tokenize(rule): state.shift(tok, value) try: return state.result except ValueError: # Couldn't parse the rule LOG.exception(_("Failed to understand rule %(rule)r") % locals()) # Fail closed return FalseCheck() def parse_rule(rule): """ Parses a policy rule into a tree of Check objects. """ # If the rule is a string, it's in the policy language if isinstance(rule, basestring): return _parse_text_rule(rule) return _parse_list_rule(rule) def register(name, func=None): """ Register a function or Check class as a policy check. :param name: Gives the name of the check type, e.g., 'rule', 'role', etc. If name is None, a default check type will be registered. :param func: If given, provides the function or class to register. If not given, returns a function taking one argument to specify the function or class to register, allowing use as a decorator. """ # Perform the actual decoration by registering the function or # class. Returns the function or class for compliance with the # decorator interface. def decorator(func): _checks[name] = func return func # If the function or class is given, do the registration if func: return decorator(func) return decorator @register("rule") class RuleCheck(Check): def __call__(self, target, creds): """ Recursively checks credentials based on the defined rules. """ try: return _rules[self.match](target, creds) except KeyError: # We don't have any matching rule; fail closed return False @register("role") class RoleCheck(Check): def __call__(self, target, creds): """Check that there is a matching role in the cred dict.""" return self.match.lower() in [x.lower() for x in creds['roles']] @register('http') class HttpCheck(Check): def __call__(self, target, creds): """ Check http: rules by calling to a remote server. This example implementation simply verifies that the response is exactly 'True'. """ url = ('http:' + self.match) % target data = {'target': jsonutils.dumps(target), 'credentials': jsonutils.dumps(creds)} post_data = urllib.urlencode(data) f = urllib2.urlopen(url, post_data) return f.read() == "True" @register(None) class GenericCheck(Check): def __call__(self, target, creds): """ Check an individual match. Matches look like: tenant:%(tenant_id)s role:compute:admin """ # TODO(termie): do dict inspection via dot syntax match = self.match % target if self.kind in creds: return match == six.text_type(creds[self.kind]) return False glance-2014.1/glance/openstack/common/processutils.py0000664000175400017540000002173612323736226024030 0ustar jenkinsjenkins00000000000000# vim: tabstop=4 shiftwidth=4 softtabstop=4 # Copyright 2011 OpenStack Foundation. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ System-level utilities and helper functions. """ import os import random import shlex import signal from eventlet.green import subprocess from eventlet import greenthread from glance.openstack.common.gettextutils import _ from glance.openstack.common import log as logging LOG = logging.getLogger(__name__) class InvalidArgumentError(Exception): def __init__(self, message=None): super(InvalidArgumentError, self).__init__(message) class UnknownArgumentError(Exception): def __init__(self, message=None): super(UnknownArgumentError, self).__init__(message) class ProcessExecutionError(Exception): def __init__(self, stdout=None, stderr=None, exit_code=None, cmd=None, description=None): self.exit_code = exit_code self.stderr = stderr self.stdout = stdout self.cmd = cmd self.description = description if description is None: description = "Unexpected error while running command." if exit_code is None: exit_code = '-' message = ("%s\nCommand: %s\nExit code: %s\nStdout: %r\nStderr: %r" % (description, cmd, exit_code, stdout, stderr)) super(ProcessExecutionError, self).__init__(message) class NoRootWrapSpecified(Exception): def __init__(self, message=None): super(NoRootWrapSpecified, self).__init__(message) def _subprocess_setup(): # Python installs a SIGPIPE handler by default. This is usually not what # non-Python subprocesses expect. signal.signal(signal.SIGPIPE, signal.SIG_DFL) def execute(*cmd, **kwargs): """ Helper method to shell out and execute a command through subprocess with optional retry. :param cmd: Passed to subprocess.Popen. :type cmd: string :param process_input: Send to opened process. :type process_input: string :param check_exit_code: Single bool, int, or list of allowed exit codes. Defaults to [0]. Raise :class:`ProcessExecutionError` unless program exits with one of these code. :type check_exit_code: boolean, int, or [int] :param delay_on_retry: True | False. Defaults to True. If set to True, wait a short amount of time before retrying. :type delay_on_retry: boolean :param attempts: How many times to retry cmd. :type attempts: int :param run_as_root: True | False. Defaults to False. If set to True, the command is prefixed by the command specified in the root_helper kwarg. :type run_as_root: boolean :param root_helper: command to prefix to commands called with run_as_root=True :type root_helper: string :param shell: whether or not there should be a shell used to execute this command. Defaults to false. :type shell: boolean :returns: (stdout, stderr) from process execution :raises: :class:`UnknownArgumentError` on receiving unknown arguments :raises: :class:`ProcessExecutionError` """ process_input = kwargs.pop('process_input', None) check_exit_code = kwargs.pop('check_exit_code', [0]) ignore_exit_code = False delay_on_retry = kwargs.pop('delay_on_retry', True) attempts = kwargs.pop('attempts', 1) run_as_root = kwargs.pop('run_as_root', False) root_helper = kwargs.pop('root_helper', '') shell = kwargs.pop('shell', False) if isinstance(check_exit_code, bool): ignore_exit_code = not check_exit_code check_exit_code = [0] elif isinstance(check_exit_code, int): check_exit_code = [check_exit_code] if kwargs: raise UnknownArgumentError(_('Got unknown keyword args ' 'to utils.execute: %r') % kwargs) if run_as_root and os.geteuid() != 0: if not root_helper: raise NoRootWrapSpecified( message=('Command requested root, but did not specify a root ' 'helper.')) cmd = shlex.split(root_helper) + list(cmd) cmd = map(str, cmd) while attempts > 0: attempts -= 1 try: LOG.debug(_('Running cmd (subprocess): %s'), ' '.join(cmd)) _PIPE = subprocess.PIPE # pylint: disable=E1101 if os.name == 'nt': preexec_fn = None close_fds = False else: preexec_fn = _subprocess_setup close_fds = True obj = subprocess.Popen(cmd, stdin=_PIPE, stdout=_PIPE, stderr=_PIPE, close_fds=close_fds, preexec_fn=preexec_fn, shell=shell) result = None if process_input is not None: result = obj.communicate(process_input) else: result = obj.communicate() obj.stdin.close() # pylint: disable=E1101 _returncode = obj.returncode # pylint: disable=E1101 if _returncode: LOG.debug(_('Result was %s') % _returncode) if not ignore_exit_code and _returncode not in check_exit_code: (stdout, stderr) = result raise ProcessExecutionError(exit_code=_returncode, stdout=stdout, stderr=stderr, cmd=' '.join(cmd)) return result except ProcessExecutionError: if not attempts: raise else: LOG.debug(_('%r failed. Retrying.'), cmd) if delay_on_retry: greenthread.sleep(random.randint(20, 200) / 100.0) finally: # NOTE(termie): this appears to be necessary to let the subprocess # call clean something up in between calls, without # it two execute calls in a row hangs the second one greenthread.sleep(0) def trycmd(*args, **kwargs): """ A wrapper around execute() to more easily handle warnings and errors. Returns an (out, err) tuple of strings containing the output of the command's stdout and stderr. If 'err' is not empty then the command can be considered to have failed. :discard_warnings True | False. Defaults to False. If set to True, then for succeeding commands, stderr is cleared """ discard_warnings = kwargs.pop('discard_warnings', False) try: out, err = execute(*args, **kwargs) failed = False except ProcessExecutionError, exn: out, err = '', str(exn) failed = True if not failed and discard_warnings and err: # Handle commands that output to stderr but otherwise succeed err = '' return out, err def ssh_execute(ssh, cmd, process_input=None, addl_env=None, check_exit_code=True): LOG.debug(_('Running cmd (SSH): %s'), cmd) if addl_env: raise InvalidArgumentError(_('Environment not supported over SSH')) if process_input: # This is (probably) fixable if we need it... raise InvalidArgumentError(_('process_input not supported over SSH')) stdin_stream, stdout_stream, stderr_stream = ssh.exec_command(cmd) channel = stdout_stream.channel # NOTE(justinsb): This seems suspicious... # ...other SSH clients have buffering issues with this approach stdout = stdout_stream.read() stderr = stderr_stream.read() stdin_stream.close() exit_status = channel.recv_exit_status() # exit_status == -1 if no exit code was returned if exit_status != -1: LOG.debug(_('Result was %s') % exit_status) if check_exit_code and exit_status != 0: raise ProcessExecutionError(exit_code=exit_status, stdout=stdout, stderr=stderr, cmd=cmd) return (stdout, stderr) glance-2014.1/glance/openstack/common/jsonutils.py0000664000175400017540000001506712323736226023323 0ustar jenkinsjenkins00000000000000# Copyright 2010 United States Government as represented by the # Administrator of the National Aeronautics and Space Administration. # Copyright 2011 Justin Santa Barbara # 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. ''' JSON related utilities. This module provides a few things: 1) A handy function for getting an object down to something that can be JSON serialized. See to_primitive(). 2) Wrappers around loads() and dumps(). The dumps() wrapper will automatically use to_primitive() for you if needed. 3) This sets up anyjson to use the loads() and dumps() wrappers if anyjson is available. ''' import datetime import functools import inspect import itertools import json try: import xmlrpclib except ImportError: # NOTE(jaypipes): xmlrpclib was renamed to xmlrpc.client in Python3 # however the function and object call signatures # remained the same. This whole try/except block should # be removed and replaced with a call to six.moves once # six 1.4.2 is released. See http://bit.ly/1bqrVzu import xmlrpc.client as xmlrpclib import six from glance.openstack.common import gettextutils from glance.openstack.common import importutils from glance.openstack.common import timeutils netaddr = importutils.try_import("netaddr") _nasty_type_tests = [inspect.ismodule, inspect.isclass, inspect.ismethod, inspect.isfunction, inspect.isgeneratorfunction, inspect.isgenerator, inspect.istraceback, inspect.isframe, inspect.iscode, inspect.isbuiltin, inspect.isroutine, inspect.isabstract] _simple_types = (six.string_types + six.integer_types + (type(None), bool, float)) def to_primitive(value, convert_instances=False, convert_datetime=True, level=0, max_depth=3): """Convert a complex object into primitives. Handy for JSON serialization. We can optionally handle instances, but since this is a recursive function, we could have cyclical data structures. To handle cyclical data structures we could track the actual objects visited in a set, but not all objects are hashable. Instead we just track the depth of the object inspections and don't go too deep. Therefore, convert_instances=True is lossy ... be aware. """ # handle obvious types first - order of basic types determined by running # full tests on nova project, resulting in the following counts: # 572754 # 460353 # 379632 # 274610 # 199918 # 114200 # 51817 # 26164 # 6491 # 283 # 19 if isinstance(value, _simple_types): return value if isinstance(value, datetime.datetime): if convert_datetime: return timeutils.strtime(value) else: return value # value of itertools.count doesn't get caught by nasty_type_tests # and results in infinite loop when list(value) is called. if type(value) == itertools.count: return six.text_type(value) # FIXME(vish): Workaround for LP bug 852095. Without this workaround, # tests that raise an exception in a mocked method that # has a @wrap_exception with a notifier will fail. If # we up the dependency to 0.5.4 (when it is released) we # can remove this workaround. if getattr(value, '__module__', None) == 'mox': return 'mock' if level > max_depth: return '?' # The try block may not be necessary after the class check above, # but just in case ... try: recursive = functools.partial(to_primitive, convert_instances=convert_instances, convert_datetime=convert_datetime, level=level, max_depth=max_depth) if isinstance(value, dict): return dict((k, recursive(v)) for k, v in six.iteritems(value)) elif isinstance(value, (list, tuple)): return [recursive(lv) for lv in value] # It's not clear why xmlrpclib created their own DateTime type, but # for our purposes, make it a datetime type which is explicitly # handled if isinstance(value, xmlrpclib.DateTime): value = datetime.datetime(*tuple(value.timetuple())[:6]) if convert_datetime and isinstance(value, datetime.datetime): return timeutils.strtime(value) elif isinstance(value, gettextutils.Message): return value.data elif hasattr(value, 'iteritems'): return recursive(dict(value.iteritems()), level=level + 1) elif hasattr(value, '__iter__'): return recursive(list(value)) elif convert_instances and hasattr(value, '__dict__'): # Likely an instance of something. Watch for cycles. # Ignore class member vars. return recursive(value.__dict__, level=level + 1) elif netaddr and isinstance(value, netaddr.IPAddress): return six.text_type(value) else: if any(test(value) for test in _nasty_type_tests): return six.text_type(value) return value except TypeError: # Class objects are tricky since they may define something like # __iter__ defined but it isn't callable as list(). return six.text_type(value) def dumps(value, default=to_primitive, **kwargs): return json.dumps(value, default=default, **kwargs) def loads(s): return json.loads(s) def load(s): return json.load(s) try: import anyjson except ImportError: pass else: anyjson._modules.append((__name__, 'dumps', TypeError, 'loads', ValueError, 'load')) anyjson.force_implementation(__name__) glance-2014.1/glance/openstack/common/gettextutils.py0000664000175400017540000004454212323736226024036 0ustar jenkinsjenkins00000000000000# Copyright 2012 Red Hat, Inc. # Copyright 2013 IBM Corp. # 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. """ gettext for openstack-common modules. Usual usage in an openstack.common module: from glance.openstack.common.gettextutils import _ """ import copy import functools import gettext import locale from logging import handlers import os import re from babel import localedata import six _localedir = os.environ.get('glance'.upper() + '_LOCALEDIR') _t = gettext.translation('glance', localedir=_localedir, fallback=True) # We use separate translation catalogs for each log level, so set up a # mapping between the log level name and the translator. The domain # for the log level is project_name + "-log-" + log_level so messages # for each level end up in their own catalog. _t_log_levels = dict( (level, gettext.translation('glance' + '-log-' + level, localedir=_localedir, fallback=True)) for level in ['info', 'warning', 'error', 'critical'] ) _AVAILABLE_LANGUAGES = {} USE_LAZY = False def enable_lazy(): """Convenience function for configuring _() to use lazy gettext Call this at the start of execution to enable the gettextutils._ function to use lazy gettext functionality. This is useful if your project is importing _ directly instead of using the gettextutils.install() way of importing the _ function. """ global USE_LAZY USE_LAZY = True def _(msg): if USE_LAZY: return Message(msg, domain='glance') else: if six.PY3: return _t.gettext(msg) return _t.ugettext(msg) def _log_translation(msg, level): """Build a single translation of a log message """ if USE_LAZY: return Message(msg, domain='glance' + '-log-' + level) else: translator = _t_log_levels[level] if six.PY3: return translator.gettext(msg) return translator.ugettext(msg) # Translators for log levels. # # The abbreviated names are meant to reflect the usual use of a short # name like '_'. The "L" is for "log" and the other letter comes from # the level. _LI = functools.partial(_log_translation, level='info') _LW = functools.partial(_log_translation, level='warning') _LE = functools.partial(_log_translation, level='error') _LC = functools.partial(_log_translation, level='critical') def install(domain, lazy=False): """Install a _() function using the given translation domain. Given a translation domain, install a _() function using gettext's install() function. The main difference from gettext.install() is that we allow overriding the default localedir (e.g. /usr/share/locale) using a translation-domain-specific environment variable (e.g. NOVA_LOCALEDIR). :param domain: the translation domain :param lazy: indicates whether or not to install the lazy _() function. The lazy _() introduces a way to do deferred translation of messages by installing a _ that builds Message objects, instead of strings, which can then be lazily translated into any available locale. """ if lazy: # NOTE(mrodden): Lazy gettext functionality. # # The following introduces a deferred way to do translations on # messages in OpenStack. We override the standard _() function # and % (format string) operation to build Message objects that can # later be translated when we have more information. def _lazy_gettext(msg): """Create and return a Message object. Lazy gettext function for a given domain, it is a factory method for a project/module to get a lazy gettext function for its own translation domain (i.e. nova, glance, cinder, etc.) Message encapsulates a string so that we can translate it later when needed. """ return Message(msg, domain=domain) from six import moves moves.builtins.__dict__['_'] = _lazy_gettext else: localedir = '%s_LOCALEDIR' % domain.upper() if six.PY3: gettext.install(domain, localedir=os.environ.get(localedir)) else: gettext.install(domain, localedir=os.environ.get(localedir), unicode=True) class Message(six.text_type): """A Message object is a unicode object that can be translated. Translation of Message is done explicitly using the translate() method. For all non-translation intents and purposes, a Message is simply unicode, and can be treated as such. """ def __new__(cls, msgid, msgtext=None, params=None, domain='glance', *args): """Create a new Message object. In order for translation to work gettext requires a message ID, this msgid will be used as the base unicode text. It is also possible for the msgid and the base unicode text to be different by passing the msgtext parameter. """ # If the base msgtext is not given, we use the default translation # of the msgid (which is in English) just in case the system locale is # not English, so that the base text will be in that locale by default. if not msgtext: msgtext = Message._translate_msgid(msgid, domain) # We want to initialize the parent unicode with the actual object that # would have been plain unicode if 'Message' was not enabled. msg = super(Message, cls).__new__(cls, msgtext) msg.msgid = msgid msg.domain = domain msg.params = params return msg def translate(self, desired_locale=None): """Translate this message to the desired locale. :param desired_locale: The desired locale to translate the message to, if no locale is provided the message will be translated to the system's default locale. :returns: the translated message in unicode """ translated_message = Message._translate_msgid(self.msgid, self.domain, desired_locale) if self.params is None: # No need for more translation return translated_message # This Message object may have been formatted with one or more # Message objects as substitution arguments, given either as a single # argument, part of a tuple, or as one or more values in a dictionary. # When translating this Message we need to translate those Messages too translated_params = _translate_args(self.params, desired_locale) translated_message = translated_message % translated_params return translated_message @staticmethod def _translate_msgid(msgid, domain, desired_locale=None): if not desired_locale: system_locale = locale.getdefaultlocale() # If the system locale is not available to the runtime use English if not system_locale[0]: desired_locale = 'en_US' else: desired_locale = system_locale[0] locale_dir = os.environ.get(domain.upper() + '_LOCALEDIR') lang = gettext.translation(domain, localedir=locale_dir, languages=[desired_locale], fallback=True) if six.PY3: translator = lang.gettext else: translator = lang.ugettext translated_message = translator(msgid) return translated_message def __mod__(self, other): # When we mod a Message we want the actual operation to be performed # by the parent class (i.e. unicode()), the only thing we do here is # save the original msgid and the parameters in case of a translation params = self._sanitize_mod_params(other) unicode_mod = super(Message, self).__mod__(params) modded = Message(self.msgid, msgtext=unicode_mod, params=params, domain=self.domain) return modded def _sanitize_mod_params(self, other): """Sanitize the object being modded with this Message. - Add support for modding 'None' so translation supports it - Trim the modded object, which can be a large dictionary, to only those keys that would actually be used in a translation - Snapshot the object being modded, in case the message is translated, it will be used as it was when the Message was created """ if other is None: params = (other,) elif isinstance(other, dict): params = self._trim_dictionary_parameters(other) else: params = self._copy_param(other) return params def _trim_dictionary_parameters(self, dict_param): """Return a dict that only has matching entries in the msgid.""" # NOTE(luisg): Here we trim down the dictionary passed as parameters # to avoid carrying a lot of unnecessary weight around in the message # object, for example if someone passes in Message() % locals() but # only some params are used, and additionally we prevent errors for # non-deepcopyable objects by unicoding() them. # Look for %(param) keys in msgid; # Skip %% and deal with the case where % is first character on the line keys = re.findall('(?:[^%]|^)?%\((\w*)\)[a-z]', self.msgid) # If we don't find any %(param) keys but have a %s if not keys and re.findall('(?:[^%]|^)%[a-z]', self.msgid): # Apparently the full dictionary is the parameter params = self._copy_param(dict_param) else: params = {} # Save our existing parameters as defaults to protect # ourselves from losing values if we are called through an # (erroneous) chain that builds a valid Message with # arguments, and then does something like "msg % kwds" # where kwds is an empty dictionary. src = {} if isinstance(self.params, dict): src.update(self.params) src.update(dict_param) for key in keys: params[key] = self._copy_param(src[key]) return params def _copy_param(self, param): try: return copy.deepcopy(param) except TypeError: # Fallback to casting to unicode this will handle the # python code-like objects that can't be deep-copied return six.text_type(param) def __add__(self, other): msg = _('Message objects do not support addition.') raise TypeError(msg) def __radd__(self, other): return self.__add__(other) def __str__(self): # NOTE(luisg): Logging in python 2.6 tries to str() log records, # and it expects specifically a UnicodeError in order to proceed. msg = _('Message objects do not support str() because they may ' 'contain non-ascii characters. ' 'Please use unicode() or translate() instead.') raise UnicodeError(msg) def get_available_languages(domain): """Lists the available languages for the given translation domain. :param domain: the domain to get languages for """ if domain in _AVAILABLE_LANGUAGES: return copy.copy(_AVAILABLE_LANGUAGES[domain]) localedir = '%s_LOCALEDIR' % domain.upper() find = lambda x: gettext.find(domain, localedir=os.environ.get(localedir), languages=[x]) # NOTE(mrodden): en_US should always be available (and first in case # order matters) since our in-line message strings are en_US language_list = ['en_US'] # NOTE(luisg): Babel <1.0 used a function called list(), which was # renamed to locale_identifiers() in >=1.0, the requirements master list # requires >=0.9.6, uncapped, so defensively work with both. We can remove # this check when the master list updates to >=1.0, and update all projects list_identifiers = (getattr(localedata, 'list', None) or getattr(localedata, 'locale_identifiers')) locale_identifiers = list_identifiers() for i in locale_identifiers: if find(i) is not None: language_list.append(i) # NOTE(luisg): Babel>=1.0,<1.3 has a bug where some OpenStack supported # locales (e.g. 'zh_CN', and 'zh_TW') aren't supported even though they # are perfectly legitimate locales: # https://github.com/mitsuhiko/babel/issues/37 # In Babel 1.3 they fixed the bug and they support these locales, but # they are still not explicitly "listed" by locale_identifiers(). # That is why we add the locales here explicitly if necessary so that # they are listed as supported. aliases = {'zh': 'zh_CN', 'zh_Hant_HK': 'zh_HK', 'zh_Hant': 'zh_TW', 'fil': 'tl_PH'} for (locale, alias) in six.iteritems(aliases): if locale in language_list and alias not in language_list: language_list.append(alias) _AVAILABLE_LANGUAGES[domain] = language_list return copy.copy(language_list) def translate(obj, desired_locale=None): """Gets the translated unicode representation of the given object. If the object is not translatable it is returned as-is. If the locale is None the object is translated to the system locale. :param obj: the object to translate :param desired_locale: the locale to translate the message to, if None the default system locale will be used :returns: the translated object in unicode, or the original object if it could not be translated """ message = obj if not isinstance(message, Message): # If the object to translate is not already translatable, # let's first get its unicode representation message = six.text_type(obj) if isinstance(message, Message): # Even after unicoding() we still need to check if we are # running with translatable unicode before translating return message.translate(desired_locale) return obj def _translate_args(args, desired_locale=None): """Translates all the translatable elements of the given arguments object. This method is used for translating the translatable values in method arguments which include values of tuples or dictionaries. If the object is not a tuple or a dictionary the object itself is translated if it is translatable. If the locale is None the object is translated to the system locale. :param args: the args to translate :param desired_locale: the locale to translate the args to, if None the default system locale will be used :returns: a new args object with the translated contents of the original """ if isinstance(args, tuple): return tuple(translate(v, desired_locale) for v in args) if isinstance(args, dict): translated_dict = {} for (k, v) in six.iteritems(args): translated_v = translate(v, desired_locale) translated_dict[k] = translated_v return translated_dict return translate(args, desired_locale) class TranslationHandler(handlers.MemoryHandler): """Handler that translates records before logging them. The TranslationHandler takes a locale and a target logging.Handler object to forward LogRecord objects to after translating them. This handler depends on Message objects being logged, instead of regular strings. The handler can be configured declaratively in the logging.conf as follows: [handlers] keys = translatedlog, translator [handler_translatedlog] class = handlers.WatchedFileHandler args = ('/var/log/api-localized.log',) formatter = context [handler_translator] class = openstack.common.log.TranslationHandler target = translatedlog args = ('zh_CN',) If the specified locale is not available in the system, the handler will log in the default locale. """ def __init__(self, locale=None, target=None): """Initialize a TranslationHandler :param locale: locale to use for translating messages :param target: logging.Handler object to forward LogRecord objects to after translation """ # NOTE(luisg): In order to allow this handler to be a wrapper for # other handlers, such as a FileHandler, and still be able to # configure it using logging.conf, this handler has to extend # MemoryHandler because only the MemoryHandlers' logging.conf # parsing is implemented such that it accepts a target handler. handlers.MemoryHandler.__init__(self, capacity=0, target=target) self.locale = locale def setFormatter(self, fmt): self.target.setFormatter(fmt) def emit(self, record): # We save the message from the original record to restore it # after translation, so other handlers are not affected by this original_msg = record.msg original_args = record.args try: self._translate_and_log_record(record) finally: record.msg = original_msg record.args = original_args def _translate_and_log_record(self, record): record.msg = translate(record.msg, self.locale) # In addition to translating the message, we also need to translate # arguments that were passed to the log method that were not part # of the main message e.g., log.info(_('Some message %s'), this_one)) record.args = _translate_args(record.args, self.locale) self.target.emit(record) glance-2014.1/glance/openstack/common/log.py0000664000175400017540000006062012323736226022045 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation. # Copyright 2010 United States Government as represented by the # Administrator of the National Aeronautics and Space Administration. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """Openstack logging handler. This module adds to logging functionality by adding the option to specify a context object when calling the various log methods. If the context object is not specified, default formatting is used. Additionally, an instance uuid may be passed as part of the log message, which is intended to make it easier for admins to find messages related to a specific instance. It also allows setting of formatting information through conf. """ import inspect import itertools import logging import logging.config import logging.handlers import os import re import sys import traceback from oslo.config import cfg import six from six import moves from glance.openstack.common.gettextutils import _ from glance.openstack.common import importutils from glance.openstack.common import jsonutils from glance.openstack.common import local _DEFAULT_LOG_DATE_FORMAT = "%Y-%m-%d %H:%M:%S" _SANITIZE_KEYS = ['adminPass', 'admin_pass', 'password', 'admin_password'] # NOTE(ldbragst): Let's build a list of regex objects using the list of # _SANITIZE_KEYS we already have. This way, we only have to add the new key # to the list of _SANITIZE_KEYS and we can generate regular expressions # for XML and JSON automatically. _SANITIZE_PATTERNS = [] _FORMAT_PATTERNS = [r'(%(key)s\s*[=]\s*[\"\']).*?([\"\'])', r'(<%(key)s>).*?()', r'([\"\']%(key)s[\"\']\s*:\s*[\"\']).*?([\"\'])', r'([\'"].*?%(key)s[\'"]\s*:\s*u?[\'"]).*?([\'"])'] for key in _SANITIZE_KEYS: for pattern in _FORMAT_PATTERNS: reg_ex = re.compile(pattern % {'key': key}, re.DOTALL) _SANITIZE_PATTERNS.append(reg_ex) common_cli_opts = [ cfg.BoolOpt('debug', short='d', default=False, help='Print debugging output (set logging level to ' 'DEBUG instead of default WARNING level).'), cfg.BoolOpt('verbose', short='v', default=False, help='Print more verbose output (set logging level to ' 'INFO instead of default WARNING level).'), ] logging_cli_opts = [ cfg.StrOpt('log-config-append', metavar='PATH', deprecated_name='log-config', help='The name of logging configuration file. It does not ' 'disable existing loggers, but just appends specified ' 'logging configuration to any other existing logging ' 'options. Please see the Python logging module ' 'documentation for details on logging configuration ' 'files.'), cfg.StrOpt('log-format', default=None, metavar='FORMAT', help='DEPRECATED. ' 'A logging.Formatter log message format string which may ' 'use any of the available logging.LogRecord attributes. ' 'This option is deprecated. Please use ' 'logging_context_format_string and ' 'logging_default_format_string instead.'), cfg.StrOpt('log-date-format', default=_DEFAULT_LOG_DATE_FORMAT, metavar='DATE_FORMAT', help='Format string for %%(asctime)s in log records. ' 'Default: %(default)s'), cfg.StrOpt('log-file', metavar='PATH', deprecated_name='logfile', help='(Optional) Name of log file to output to. ' 'If no default is set, logging will go to stdout.'), cfg.StrOpt('log-dir', deprecated_name='logdir', help='(Optional) The base directory used for relative ' '--log-file paths'), cfg.BoolOpt('use-syslog', default=False, help='Use syslog for logging. ' 'Existing syslog format is DEPRECATED during I, ' 'and then will be changed in J to honor RFC5424'), cfg.BoolOpt('use-syslog-rfc-format', # TODO(bogdando) remove or use True after existing # syslog format deprecation in J default=False, help='(Optional) Use syslog rfc5424 format for logging. ' 'If enabled, will add APP-NAME (RFC5424) before the ' 'MSG part of the syslog message. The old format ' 'without APP-NAME is deprecated in I, ' 'and will be removed in J.'), cfg.StrOpt('syslog-log-facility', default='LOG_USER', help='Syslog facility to receive log lines') ] generic_log_opts = [ cfg.BoolOpt('use_stderr', default=True, help='Log output to standard error') ] log_opts = [ cfg.StrOpt('logging_context_format_string', default='%(asctime)s.%(msecs)03d %(process)d %(levelname)s ' '%(name)s [%(request_id)s %(user_identity)s] ' '%(instance)s%(message)s', help='Format string to use for log messages with context'), cfg.StrOpt('logging_default_format_string', default='%(asctime)s.%(msecs)03d %(process)d %(levelname)s ' '%(name)s [-] %(instance)s%(message)s', help='Format string to use for log messages without context'), cfg.StrOpt('logging_debug_format_suffix', default='%(funcName)s %(pathname)s:%(lineno)d', help='Data to append to log format when level is DEBUG'), cfg.StrOpt('logging_exception_prefix', default='%(asctime)s.%(msecs)03d %(process)d TRACE %(name)s ' '%(instance)s', help='Prefix each line of exception output with this format'), cfg.ListOpt('default_log_levels', default=[ 'amqp=WARN', 'amqplib=WARN', 'boto=WARN', 'qpid=WARN', 'sqlalchemy=WARN', 'suds=INFO', 'iso8601=WARN', 'requests.packages.urllib3.connectionpool=WARN' ], help='List of logger=LEVEL pairs'), cfg.BoolOpt('publish_errors', default=False, help='Publish error events'), cfg.BoolOpt('fatal_deprecations', default=False, help='Make deprecations fatal'), # NOTE(mikal): there are two options here because sometimes we are handed # a full instance (and could include more information), and other times we # are just handed a UUID for the instance. cfg.StrOpt('instance_format', default='[instance: %(uuid)s] ', help='If an instance is passed with the log message, format ' 'it like this'), cfg.StrOpt('instance_uuid_format', default='[instance: %(uuid)s] ', help='If an instance UUID is passed with the log message, ' 'format it like this'), ] CONF = cfg.CONF CONF.register_cli_opts(common_cli_opts) CONF.register_cli_opts(logging_cli_opts) CONF.register_opts(generic_log_opts) CONF.register_opts(log_opts) # our new audit level # NOTE(jkoelker) Since we synthesized an audit level, make the logging # module aware of it so it acts like other levels. logging.AUDIT = logging.INFO + 1 logging.addLevelName(logging.AUDIT, 'AUDIT') try: NullHandler = logging.NullHandler except AttributeError: # NOTE(jkoelker) NullHandler added in Python 2.7 class NullHandler(logging.Handler): def handle(self, record): pass def emit(self, record): pass def createLock(self): self.lock = None def _dictify_context(context): if context is None: return None if not isinstance(context, dict) and getattr(context, 'to_dict', None): context = context.to_dict() return context def _get_binary_name(): return os.path.basename(inspect.stack()[-1][1]) def _get_log_file_path(binary=None): logfile = CONF.log_file logdir = CONF.log_dir if logfile and not logdir: return logfile if logfile and logdir: return os.path.join(logdir, logfile) if logdir: binary = binary or _get_binary_name() return '%s.log' % (os.path.join(logdir, binary),) return None def mask_password(message, secret="***"): """Replace password with 'secret' in message. :param message: The string which includes security information. :param secret: value with which to replace passwords. :returns: The unicode value of message with the password fields masked. For example: >>> mask_password("'adminPass' : 'aaaaa'") "'adminPass' : '***'" >>> mask_password("'admin_pass' : 'aaaaa'") "'admin_pass' : '***'" >>> mask_password('"password" : "aaaaa"') '"password" : "***"' >>> mask_password("'original_password' : 'aaaaa'") "'original_password' : '***'" >>> mask_password("u'original_password' : u'aaaaa'") "u'original_password' : u'***'" """ message = six.text_type(message) # NOTE(ldbragst): Check to see if anything in message contains any key # specified in _SANITIZE_KEYS, if not then just return the message since # we don't have to mask any passwords. if not any(key in message for key in _SANITIZE_KEYS): return message secret = r'\g<1>' + secret + r'\g<2>' for pattern in _SANITIZE_PATTERNS: message = re.sub(pattern, secret, message) return message class BaseLoggerAdapter(logging.LoggerAdapter): def audit(self, msg, *args, **kwargs): self.log(logging.AUDIT, msg, *args, **kwargs) class LazyAdapter(BaseLoggerAdapter): def __init__(self, name='unknown', version='unknown'): self._logger = None self.extra = {} self.name = name self.version = version @property def logger(self): if not self._logger: self._logger = getLogger(self.name, self.version) return self._logger class ContextAdapter(BaseLoggerAdapter): warn = logging.LoggerAdapter.warning def __init__(self, logger, project_name, version_string): self.logger = logger self.project = project_name self.version = version_string @property def handlers(self): return self.logger.handlers def deprecated(self, msg, *args, **kwargs): stdmsg = _("Deprecated: %s") % msg if CONF.fatal_deprecations: self.critical(stdmsg, *args, **kwargs) raise DeprecatedConfig(msg=stdmsg) else: self.warn(stdmsg, *args, **kwargs) def process(self, msg, kwargs): # NOTE(mrodden): catch any Message/other object and # coerce to unicode before they can get # to the python logging and possibly # cause string encoding trouble if not isinstance(msg, six.string_types): msg = six.text_type(msg) if 'extra' not in kwargs: kwargs['extra'] = {} extra = kwargs['extra'] context = kwargs.pop('context', None) if not context: context = getattr(local.store, 'context', None) if context: extra.update(_dictify_context(context)) instance = kwargs.pop('instance', None) instance_uuid = (extra.get('instance_uuid', None) or kwargs.pop('instance_uuid', None)) instance_extra = '' if instance: instance_extra = CONF.instance_format % instance elif instance_uuid: instance_extra = (CONF.instance_uuid_format % {'uuid': instance_uuid}) extra['instance'] = instance_extra extra.setdefault('user_identity', kwargs.pop('user_identity', None)) extra['project'] = self.project extra['version'] = self.version extra['extra'] = extra.copy() return msg, kwargs class JSONFormatter(logging.Formatter): def __init__(self, fmt=None, datefmt=None): # NOTE(jkoelker) we ignore the fmt argument, but its still there # since logging.config.fileConfig passes it. self.datefmt = datefmt def formatException(self, ei, strip_newlines=True): lines = traceback.format_exception(*ei) if strip_newlines: lines = [moves.filter( lambda x: x, line.rstrip().splitlines()) for line in lines] lines = list(itertools.chain(*lines)) return lines def format(self, record): message = {'message': record.getMessage(), 'asctime': self.formatTime(record, self.datefmt), 'name': record.name, 'msg': record.msg, 'args': record.args, 'levelname': record.levelname, 'levelno': record.levelno, 'pathname': record.pathname, 'filename': record.filename, 'module': record.module, 'lineno': record.lineno, 'funcname': record.funcName, 'created': record.created, 'msecs': record.msecs, 'relative_created': record.relativeCreated, 'thread': record.thread, 'thread_name': record.threadName, 'process_name': record.processName, 'process': record.process, 'traceback': None} if hasattr(record, 'extra'): message['extra'] = record.extra if record.exc_info: message['traceback'] = self.formatException(record.exc_info) return jsonutils.dumps(message) def _create_logging_excepthook(product_name): def logging_excepthook(exc_type, value, tb): extra = {} if CONF.verbose or CONF.debug: extra['exc_info'] = (exc_type, value, tb) getLogger(product_name).critical( "".join(traceback.format_exception_only(exc_type, value)), **extra) return logging_excepthook class LogConfigError(Exception): message = _('Error loading logging config %(log_config)s: %(err_msg)s') def __init__(self, log_config, err_msg): self.log_config = log_config self.err_msg = err_msg def __str__(self): return self.message % dict(log_config=self.log_config, err_msg=self.err_msg) def _load_log_config(log_config_append): try: logging.config.fileConfig(log_config_append, disable_existing_loggers=False) except moves.configparser.Error as exc: raise LogConfigError(log_config_append, str(exc)) def setup(product_name, version='unknown'): """Setup logging.""" if CONF.log_config_append: _load_log_config(CONF.log_config_append) else: _setup_logging_from_conf(product_name, version) sys.excepthook = _create_logging_excepthook(product_name) def set_defaults(logging_context_format_string): cfg.set_defaults(log_opts, logging_context_format_string= logging_context_format_string) def _find_facility_from_conf(): facility_names = logging.handlers.SysLogHandler.facility_names facility = getattr(logging.handlers.SysLogHandler, CONF.syslog_log_facility, None) if facility is None and CONF.syslog_log_facility in facility_names: facility = facility_names.get(CONF.syslog_log_facility) if facility is None: valid_facilities = facility_names.keys() consts = ['LOG_AUTH', 'LOG_AUTHPRIV', 'LOG_CRON', 'LOG_DAEMON', 'LOG_FTP', 'LOG_KERN', 'LOG_LPR', 'LOG_MAIL', 'LOG_NEWS', 'LOG_AUTH', 'LOG_SYSLOG', 'LOG_USER', 'LOG_UUCP', 'LOG_LOCAL0', 'LOG_LOCAL1', 'LOG_LOCAL2', 'LOG_LOCAL3', 'LOG_LOCAL4', 'LOG_LOCAL5', 'LOG_LOCAL6', 'LOG_LOCAL7'] valid_facilities.extend(consts) raise TypeError(_('syslog facility must be one of: %s') % ', '.join("'%s'" % fac for fac in valid_facilities)) return facility class RFCSysLogHandler(logging.handlers.SysLogHandler): def __init__(self, *args, **kwargs): self.binary_name = _get_binary_name() super(RFCSysLogHandler, self).__init__(*args, **kwargs) def format(self, record): msg = super(RFCSysLogHandler, self).format(record) msg = self.binary_name + ' ' + msg return msg def _setup_logging_from_conf(project, version): log_root = getLogger(None).logger for handler in log_root.handlers: log_root.removeHandler(handler) if CONF.use_syslog: facility = _find_facility_from_conf() # TODO(bogdando) use the format provided by RFCSysLogHandler # after existing syslog format deprecation in J if CONF.use_syslog_rfc_format: syslog = RFCSysLogHandler(address='/dev/log', facility=facility) else: syslog = logging.handlers.SysLogHandler(address='/dev/log', facility=facility) log_root.addHandler(syslog) logpath = _get_log_file_path() if logpath: filelog = logging.handlers.WatchedFileHandler(logpath) log_root.addHandler(filelog) if CONF.use_stderr: streamlog = ColorHandler() log_root.addHandler(streamlog) elif not logpath: # pass sys.stdout as a positional argument # python2.6 calls the argument strm, in 2.7 it's stream streamlog = logging.StreamHandler(sys.stdout) log_root.addHandler(streamlog) if CONF.publish_errors: handler = importutils.import_object( "glance.openstack.common.log_handler.PublishErrorsHandler", logging.ERROR) log_root.addHandler(handler) datefmt = CONF.log_date_format for handler in log_root.handlers: # NOTE(alaski): CONF.log_format overrides everything currently. This # should be deprecated in favor of context aware formatting. if CONF.log_format: handler.setFormatter(logging.Formatter(fmt=CONF.log_format, datefmt=datefmt)) log_root.info('Deprecated: log_format is now deprecated and will ' 'be removed in the next release') else: handler.setFormatter(ContextFormatter(project=project, version=version, datefmt=datefmt)) if CONF.debug: log_root.setLevel(logging.DEBUG) elif CONF.verbose: log_root.setLevel(logging.INFO) else: log_root.setLevel(logging.WARNING) for pair in CONF.default_log_levels: mod, _sep, level_name = pair.partition('=') level = logging.getLevelName(level_name) logger = logging.getLogger(mod) logger.setLevel(level) _loggers = {} def getLogger(name='unknown', version='unknown'): if name not in _loggers: _loggers[name] = ContextAdapter(logging.getLogger(name), name, version) return _loggers[name] def getLazyLogger(name='unknown', version='unknown'): """Returns lazy logger. Creates a pass-through logger that does not create the real logger until it is really needed and delegates all calls to the real logger once it is created. """ return LazyAdapter(name, version) class WritableLogger(object): """A thin wrapper that responds to `write` and logs.""" def __init__(self, logger, level=logging.INFO): self.logger = logger self.level = level def write(self, msg): self.logger.log(self.level, msg.rstrip()) class ContextFormatter(logging.Formatter): """A context.RequestContext aware formatter configured through flags. The flags used to set format strings are: logging_context_format_string and logging_default_format_string. You can also specify logging_debug_format_suffix to append extra formatting if the log level is debug. For information about what variables are available for the formatter see: http://docs.python.org/library/logging.html#formatter If available, uses the context value stored in TLS - local.store.context """ def __init__(self, *args, **kwargs): """Initialize ContextFormatter instance Takes additional keyword arguments which can be used in the message format string. :keyword project: project name :type project: string :keyword version: project version :type version: string """ self.project = kwargs.pop('project', 'unknown') self.version = kwargs.pop('version', 'unknown') logging.Formatter.__init__(self, *args, **kwargs) def format(self, record): """Uses contextstring if request_id is set, otherwise default.""" # store project info record.project = self.project record.version = self.version # store request info context = getattr(local.store, 'context', None) if context: d = _dictify_context(context) for k, v in d.items(): setattr(record, k, v) # NOTE(sdague): default the fancier formatting params # to an empty string so we don't throw an exception if # they get used for key in ('instance', 'color'): if key not in record.__dict__: record.__dict__[key] = '' if record.__dict__.get('request_id', None): self._fmt = CONF.logging_context_format_string else: self._fmt = CONF.logging_default_format_string if (record.levelno == logging.DEBUG and CONF.logging_debug_format_suffix): self._fmt += " " + CONF.logging_debug_format_suffix # Cache this on the record, Logger will respect our formatted copy if record.exc_info: record.exc_text = self.formatException(record.exc_info, record) return logging.Formatter.format(self, record) def formatException(self, exc_info, record=None): """Format exception output with CONF.logging_exception_prefix.""" if not record: return logging.Formatter.formatException(self, exc_info) stringbuffer = moves.StringIO() traceback.print_exception(exc_info[0], exc_info[1], exc_info[2], None, stringbuffer) lines = stringbuffer.getvalue().split('\n') stringbuffer.close() if CONF.logging_exception_prefix.find('%(asctime)') != -1: record.asctime = self.formatTime(record, self.datefmt) formatted_lines = [] for line in lines: pl = CONF.logging_exception_prefix % record.__dict__ fl = '%s%s' % (pl, line) formatted_lines.append(fl) return '\n'.join(formatted_lines) class ColorHandler(logging.StreamHandler): LEVEL_COLORS = { logging.DEBUG: '\033[00;32m', # GREEN logging.INFO: '\033[00;36m', # CYAN logging.AUDIT: '\033[01;36m', # BOLD CYAN logging.WARN: '\033[01;33m', # BOLD YELLOW logging.ERROR: '\033[01;31m', # BOLD RED logging.CRITICAL: '\033[01;31m', # BOLD RED } def format(self, record): record.color = self.LEVEL_COLORS[record.levelno] return logging.StreamHandler.format(self, record) class DeprecatedConfig(Exception): message = _("Fatal call to deprecated config: %(msg)s") def __init__(self, msg): super(Exception, self).__init__(self.message % dict(msg=msg)) glance-2014.1/glance/openstack/common/service.py0000664000175400017540000002367612323736226022736 0ustar jenkinsjenkins00000000000000# vim: tabstop=4 shiftwidth=4 softtabstop=4 # Copyright 2010 United States Government as represented by the # Administrator of the National Aeronautics and Space Administration. # Copyright 2011 Justin Santa Barbara # 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. """Generic Node base class for all workers that run on hosts.""" import errno import os import random import signal import sys import time import eventlet import logging as std_logging from oslo.config import cfg from glance.openstack.common import eventlet_backdoor from glance.openstack.common.gettextutils import _ from glance.openstack.common import importutils from glance.openstack.common import log as logging from glance.openstack.common import threadgroup rpc = importutils.try_import('glance.openstack.common.rpc') CONF = cfg.CONF LOG = logging.getLogger(__name__) class Launcher(object): """Launch one or more services and wait for them to complete.""" def __init__(self): """Initialize the service launcher. :returns: None """ self._services = threadgroup.ThreadGroup() eventlet_backdoor.initialize_if_enabled() @staticmethod def run_service(service): """Start and wait for a service to finish. :param service: service to run and wait for. :returns: None """ service.start() service.wait() def launch_service(self, service): """Load and start the given service. :param service: The service you would like to start. :returns: None """ self._services.add_thread(self.run_service, service) def stop(self): """Stop all services which are currently running. :returns: None """ self._services.stop() def wait(self): """Waits until all services have been stopped, and then returns. :returns: None """ self._services.wait() class SignalExit(SystemExit): def __init__(self, signo, exccode=1): super(SignalExit, self).__init__(exccode) self.signo = signo class ServiceLauncher(Launcher): def _handle_signal(self, signo, frame): # Allow the process to be killed again and die from natural causes signal.signal(signal.SIGTERM, signal.SIG_DFL) signal.signal(signal.SIGINT, signal.SIG_DFL) raise SignalExit(signo) def wait(self): signal.signal(signal.SIGTERM, self._handle_signal) signal.signal(signal.SIGINT, self._handle_signal) LOG.debug(_('Full set of CONF:')) CONF.log_opt_values(LOG, std_logging.DEBUG) status = None try: super(ServiceLauncher, self).wait() except SignalExit as exc: signame = {signal.SIGTERM: 'SIGTERM', signal.SIGINT: 'SIGINT'}[exc.signo] LOG.info(_('Caught %s, exiting'), signame) status = exc.code except SystemExit as exc: status = exc.code finally: if rpc: rpc.cleanup() self.stop() return status class ServiceWrapper(object): def __init__(self, service, workers): self.service = service self.workers = workers self.children = set() self.forktimes = [] class ProcessLauncher(object): def __init__(self): self.children = {} self.sigcaught = None self.running = True rfd, self.writepipe = os.pipe() self.readpipe = eventlet.greenio.GreenPipe(rfd, 'r') signal.signal(signal.SIGTERM, self._handle_signal) signal.signal(signal.SIGINT, self._handle_signal) def _handle_signal(self, signo, frame): self.sigcaught = signo self.running = False # Allow the process to be killed again and die from natural causes signal.signal(signal.SIGTERM, signal.SIG_DFL) signal.signal(signal.SIGINT, signal.SIG_DFL) def _pipe_watcher(self): # This will block until the write end is closed when the parent # dies unexpectedly self.readpipe.read() LOG.info(_('Parent process has died unexpectedly, exiting')) sys.exit(1) def _child_process(self, service): # Setup child signal handlers differently def _sigterm(*args): signal.signal(signal.SIGTERM, signal.SIG_DFL) raise SignalExit(signal.SIGTERM) signal.signal(signal.SIGTERM, _sigterm) # Block SIGINT and let the parent send us a SIGTERM signal.signal(signal.SIGINT, signal.SIG_IGN) # Reopen the eventlet hub to make sure we don't share an epoll # fd with parent and/or siblings, which would be bad eventlet.hubs.use_hub() # Close write to ensure only parent has it open os.close(self.writepipe) # Create greenthread to watch for parent to close pipe eventlet.spawn_n(self._pipe_watcher) # Reseed random number generator random.seed() launcher = Launcher() launcher.run_service(service) def _start_child(self, wrap): if len(wrap.forktimes) > wrap.workers: # Limit ourselves to one process a second (over the period of # number of workers * 1 second). This will allow workers to # start up quickly but ensure we don't fork off children that # die instantly too quickly. if time.time() - wrap.forktimes[0] < wrap.workers: LOG.info(_('Forking too fast, sleeping')) time.sleep(1) wrap.forktimes.pop(0) wrap.forktimes.append(time.time()) pid = os.fork() if pid == 0: # NOTE(johannes): All exceptions are caught to ensure this # doesn't fallback into the loop spawning children. It would # be bad for a child to spawn more children. status = 0 try: self._child_process(wrap.service) except SignalExit as exc: signame = {signal.SIGTERM: 'SIGTERM', signal.SIGINT: 'SIGINT'}[exc.signo] LOG.info(_('Caught %s, exiting'), signame) status = exc.code except SystemExit as exc: status = exc.code except BaseException: LOG.exception(_('Unhandled exception')) status = 2 finally: wrap.service.stop() os._exit(status) LOG.info(_('Started child %d'), pid) wrap.children.add(pid) self.children[pid] = wrap return pid def launch_service(self, service, workers=1): wrap = ServiceWrapper(service, workers) LOG.info(_('Starting %d workers'), wrap.workers) while self.running and len(wrap.children) < wrap.workers: self._start_child(wrap) def _wait_child(self): try: # Don't block if no child processes have exited pid, status = os.waitpid(0, os.WNOHANG) if not pid: return None except OSError as exc: if exc.errno not in (errno.EINTR, errno.ECHILD): raise return None if os.WIFSIGNALED(status): sig = os.WTERMSIG(status) LOG.info(_('Child %(pid)d killed by signal %(sig)d'), dict(pid=pid, sig=sig)) else: code = os.WEXITSTATUS(status) LOG.info(_('Child %(pid)s exited with status %(code)d'), dict(pid=pid, code=code)) if pid not in self.children: LOG.warning(_('pid %d not in child list'), pid) return None wrap = self.children.pop(pid) wrap.children.remove(pid) return wrap def wait(self): """Loop waiting on children to die and respawning as necessary""" LOG.debug(_('Full set of CONF:')) CONF.log_opt_values(LOG, std_logging.DEBUG) while self.running: wrap = self._wait_child() if not wrap: # Yield to other threads if no children have exited # Sleep for a short time to avoid excessive CPU usage # (see bug #1095346) eventlet.greenthread.sleep(.01) continue while self.running and len(wrap.children) < wrap.workers: self._start_child(wrap) if self.sigcaught: signame = {signal.SIGTERM: 'SIGTERM', signal.SIGINT: 'SIGINT'}[self.sigcaught] LOG.info(_('Caught %s, stopping children'), signame) for pid in self.children: try: os.kill(pid, signal.SIGTERM) except OSError as exc: if exc.errno != errno.ESRCH: raise # Wait for children to die if self.children: LOG.info(_('Waiting on %d children to exit'), len(self.children)) while self.children: self._wait_child() class Service(object): """Service object for binaries running on hosts.""" def __init__(self, threads=1000): self.tg = threadgroup.ThreadGroup(threads) def start(self): pass def stop(self): self.tg.stop() def wait(self): self.tg.wait() def launch(service, workers=None): if workers: launcher = ProcessLauncher() launcher.launch_service(service, workers=workers) else: launcher = ServiceLauncher() launcher.launch_service(service) return launcher glance-2014.1/glance/openstack/common/excutils.py0000664000175400017540000000717112323736226023126 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation. # Copyright 2012, Red Hat, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ Exception related utilities. """ import logging import sys import time import traceback import six from glance.openstack.common.gettextutils import _ class save_and_reraise_exception(object): """Save current exception, run some code and then re-raise. In some cases the exception context can be cleared, resulting in None being attempted to be re-raised after an exception handler is run. This can happen when eventlet switches greenthreads or when running an exception handler, code raises and catches an exception. In both cases the exception context will be cleared. To work around this, we save the exception state, run handler code, and then re-raise the original exception. If another exception occurs, the saved exception is logged and the new exception is re-raised. In some cases the caller may not want to re-raise the exception, and for those circumstances this context provides a reraise flag that can be used to suppress the exception. For example:: except Exception: with save_and_reraise_exception() as ctxt: decide_if_need_reraise() if not should_be_reraised: ctxt.reraise = False """ def __init__(self): self.reraise = True def __enter__(self): self.type_, self.value, self.tb, = sys.exc_info() return self def __exit__(self, exc_type, exc_val, exc_tb): if exc_type is not None: logging.error(_('Original exception being dropped: %s'), traceback.format_exception(self.type_, self.value, self.tb)) return False if self.reraise: six.reraise(self.type_, self.value, self.tb) def forever_retry_uncaught_exceptions(infunc): def inner_func(*args, **kwargs): last_log_time = 0 last_exc_message = None exc_count = 0 while True: try: return infunc(*args, **kwargs) except Exception as exc: this_exc_message = six.u(str(exc)) if this_exc_message == last_exc_message: exc_count += 1 else: exc_count = 1 # Do not log any more frequently than once a minute unless # the exception message changes cur_time = int(time.time()) if (cur_time - last_log_time > 60 or this_exc_message != last_exc_message): logging.exception( _('Unexpected exception occurred %d time(s)... ' 'retrying.') % exc_count) last_log_time = cur_time last_exc_message = this_exc_message exc_count = 0 # This should be a very rare event. In case it isn't, do # a sleep. time.sleep(1) return inner_func glance-2014.1/glance/openstack/common/local.py0000664000175400017540000000321512323736226022353 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """Local storage of variables using weak references""" import threading import weakref class WeakLocal(threading.local): def __getattribute__(self, attr): rval = super(WeakLocal, self).__getattribute__(attr) if rval: # NOTE(mikal): this bit is confusing. What is stored is a weak # reference, not the value itself. We therefore need to lookup # the weak reference and return the inner value here. rval = rval() return rval def __setattr__(self, attr, value): value = weakref.ref(value) return super(WeakLocal, self).__setattr__(attr, value) # NOTE(mikal): the name "store" should be deprecated in the future store = WeakLocal() # A "weak" store uses weak references and allows an object to fall out of scope # when it falls out of scope in the code that uses the thread local storage. A # "strong" store will hold a reference to the object so that it never falls out # of scope. weak_store = WeakLocal() strong_store = threading.local() glance-2014.1/glance/openstack/common/test.py0000664000175400017540000000365512323736226022250 0ustar jenkinsjenkins00000000000000# vim: tabstop=4 shiftwidth=4 softtabstop=4 # Copyright (c) 2013 Hewlett-Packard Development Company, L.P. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """Common utilities used in testing""" import os import fixtures import testtools _TRUE_VALUES = ('True', 'true', '1', 'yes') class BaseTestCase(testtools.TestCase): def setUp(self): super(BaseTestCase, self).setUp() self._set_timeout() self._fake_output() self.useFixture(fixtures.FakeLogger('glance.openstack.common')) self.useFixture(fixtures.NestedTempfile()) self.useFixture(fixtures.TempHomeDir()) def _set_timeout(self): test_timeout = os.environ.get('OS_TEST_TIMEOUT', 0) try: test_timeout = int(test_timeout) except ValueError: # If timeout value is invalid do not set a timeout. test_timeout = 0 if test_timeout > 0: self.useFixture(fixtures.Timeout(test_timeout, gentle=True)) def _fake_output(self): if os.environ.get('OS_STDOUT_CAPTURE') in _TRUE_VALUES: stdout = self.useFixture(fixtures.StringStream('stdout')).stream self.useFixture(fixtures.MonkeyPatch('sys.stdout', stdout)) if os.environ.get('OS_STDERR_CAPTURE') in _TRUE_VALUES: stderr = self.useFixture(fixtures.StringStream('stderr')).stream self.useFixture(fixtures.MonkeyPatch('sys.stderr', stderr)) glance-2014.1/glance/openstack/common/db/0000775000175400017540000000000012323736427021276 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/openstack/common/db/options.py0000664000175400017540000001776012323736226023353 0ustar jenkinsjenkins00000000000000# 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 copy from oslo.config import cfg database_opts = [ cfg.StrOpt('sqlite_db', deprecated_group='DEFAULT', default='glance.sqlite', help='The file name to use with SQLite'), cfg.BoolOpt('sqlite_synchronous', deprecated_group='DEFAULT', default=True, help='If True, SQLite uses synchronous mode'), cfg.StrOpt('backend', default='sqlalchemy', deprecated_name='db_backend', deprecated_group='DEFAULT', help='The backend to use for db'), cfg.StrOpt('connection', help='The SQLAlchemy connection string used to connect to the ' 'database', secret=True, deprecated_opts=[cfg.DeprecatedOpt('sql_connection', group='DEFAULT'), cfg.DeprecatedOpt('sql_connection', group='DATABASE'), cfg.DeprecatedOpt('connection', group='sql'), ]), cfg.StrOpt('mysql_sql_mode', default='TRADITIONAL', help='The SQL mode to be used for MySQL sessions. ' 'This option, including the default, overrides any ' 'server-set SQL mode. To use whatever SQL mode ' 'is set by the server configuration, ' 'set this to no value. Example: mysql_sql_mode='), cfg.IntOpt('idle_timeout', default=3600, deprecated_opts=[cfg.DeprecatedOpt('sql_idle_timeout', group='DEFAULT'), cfg.DeprecatedOpt('sql_idle_timeout', group='DATABASE'), cfg.DeprecatedOpt('idle_timeout', group='sql')], help='Timeout before idle sql connections are reaped'), cfg.IntOpt('min_pool_size', default=1, deprecated_opts=[cfg.DeprecatedOpt('sql_min_pool_size', group='DEFAULT'), cfg.DeprecatedOpt('sql_min_pool_size', group='DATABASE')], help='Minimum number of SQL connections to keep open in a ' 'pool'), cfg.IntOpt('max_pool_size', default=None, deprecated_opts=[cfg.DeprecatedOpt('sql_max_pool_size', group='DEFAULT'), cfg.DeprecatedOpt('sql_max_pool_size', group='DATABASE')], help='Maximum number of SQL connections to keep open in a ' 'pool'), cfg.IntOpt('max_retries', default=10, deprecated_opts=[cfg.DeprecatedOpt('sql_max_retries', group='DEFAULT'), cfg.DeprecatedOpt('sql_max_retries', group='DATABASE')], help='Maximum db connection retries during startup. ' '(setting -1 implies an infinite retry count)'), cfg.IntOpt('retry_interval', default=10, deprecated_opts=[cfg.DeprecatedOpt('sql_retry_interval', group='DEFAULT'), cfg.DeprecatedOpt('reconnect_interval', group='DATABASE')], help='Interval between retries of opening a sql connection'), cfg.IntOpt('max_overflow', default=None, deprecated_opts=[cfg.DeprecatedOpt('sql_max_overflow', group='DEFAULT'), cfg.DeprecatedOpt('sqlalchemy_max_overflow', group='DATABASE')], help='If set, use this value for max_overflow with sqlalchemy'), cfg.IntOpt('connection_debug', default=0, deprecated_opts=[cfg.DeprecatedOpt('sql_connection_debug', group='DEFAULT')], help='Verbosity of SQL debugging information. 0=None, ' '100=Everything'), cfg.BoolOpt('connection_trace', default=False, deprecated_opts=[cfg.DeprecatedOpt('sql_connection_trace', group='DEFAULT')], help='Add python stack traces to SQL as comment strings'), cfg.IntOpt('pool_timeout', default=None, deprecated_opts=[cfg.DeprecatedOpt('sqlalchemy_pool_timeout', group='DATABASE')], help='If set, use this value for pool_timeout with sqlalchemy'), cfg.BoolOpt('use_db_reconnect', default=False, help='Enable the experimental use of database reconnect ' 'on connection lost'), cfg.IntOpt('db_retry_interval', default=1, help='seconds between db connection retries'), cfg.BoolOpt('db_inc_retry_interval', default=True, help='Whether to increase interval between db connection ' 'retries, up to db_max_retry_interval'), cfg.IntOpt('db_max_retry_interval', default=10, help='max seconds between db connection retries, if ' 'db_inc_retry_interval is enabled'), cfg.IntOpt('db_max_retries', default=20, help='maximum db connection retries before error is raised. ' '(setting -1 implies an infinite retry count)'), ] CONF = cfg.CONF CONF.register_opts(database_opts, 'database') def set_defaults(sql_connection, sqlite_db, max_pool_size=None, max_overflow=None, pool_timeout=None): """Set defaults for configuration variables.""" cfg.set_defaults(database_opts, connection=sql_connection, sqlite_db=sqlite_db) # Update the QueuePool defaults if max_pool_size is not None: cfg.set_defaults(database_opts, max_pool_size=max_pool_size) if max_overflow is not None: cfg.set_defaults(database_opts, max_overflow=max_overflow) if pool_timeout is not None: cfg.set_defaults(database_opts, pool_timeout=pool_timeout) def list_opts(): """Returns a list of oslo.config options available in the library. The returned list includes all oslo.config options which may be registered at runtime by the library. Each element of the list is a tuple. The first element is the name of the group under which the list of elements in the second element will be registered. A group name of None corresponds to the [DEFAULT] group in config files. The purpose of this is to allow tools like the Oslo sample config file generator to discover the options exposed to users by this library. :returns: a list of (group_name, opts) tuples """ return [('database', copy.deepcopy(database_opts))] glance-2014.1/glance/openstack/common/db/sqlalchemy/0000775000175400017540000000000012323736427023440 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/openstack/common/db/sqlalchemy/migration.py0000664000175400017540000002374612323736226026014 0ustar jenkinsjenkins00000000000000# coding: utf-8 # # Copyright (c) 2013 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # # Base on code in migrate/changeset/databases/sqlite.py which is under # the following license: # # The MIT License # # Copyright (c) 2009 Evan Rosson, Jan Dittberner, Domen Kožar # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. import os import re from migrate.changeset import ansisql from migrate.changeset.databases import sqlite from migrate import exceptions as versioning_exceptions from migrate.versioning import api as versioning_api from migrate.versioning.repository import Repository import sqlalchemy from sqlalchemy.schema import UniqueConstraint from glance.openstack.common.db import exception from glance.openstack.common.gettextutils import _ def _get_unique_constraints(self, table): """Retrieve information about existing unique constraints of the table This feature is needed for _recreate_table() to work properly. Unfortunately, it's not available in sqlalchemy 0.7.x/0.8.x. """ data = table.metadata.bind.execute( """SELECT sql FROM sqlite_master WHERE type='table' AND name=:table_name""", table_name=table.name ).fetchone()[0] UNIQUE_PATTERN = "CONSTRAINT (\w+) UNIQUE \(([^\)]+)\)" return [ UniqueConstraint( *[getattr(table.columns, c.strip(' "')) for c in cols.split(",")], name=name ) for name, cols in re.findall(UNIQUE_PATTERN, data) ] def _recreate_table(self, table, column=None, delta=None, omit_uniques=None): """Recreate the table properly Unlike the corresponding original method of sqlalchemy-migrate this one doesn't drop existing unique constraints when creating a new one. """ table_name = self.preparer.format_table(table) # we remove all indexes so as not to have # problems during copy and re-create for index in table.indexes: index.drop() # reflect existing unique constraints for uc in self._get_unique_constraints(table): table.append_constraint(uc) # omit given unique constraints when creating a new table if required table.constraints = set([ cons for cons in table.constraints if omit_uniques is None or cons.name not in omit_uniques ]) self.append('ALTER TABLE %s RENAME TO migration_tmp' % table_name) self.execute() insertion_string = self._modify_table(table, column, delta) table.create(bind=self.connection) self.append(insertion_string % {'table_name': table_name}) self.execute() self.append('DROP TABLE migration_tmp') self.execute() def _visit_migrate_unique_constraint(self, *p, **k): """Drop the given unique constraint The corresponding original method of sqlalchemy-migrate just raises NotImplemented error """ self.recreate_table(p[0].table, omit_uniques=[p[0].name]) def patch_migrate(): """A workaround for SQLite's inability to alter things SQLite abilities to alter tables are very limited (please read http://www.sqlite.org/lang_altertable.html for more details). E. g. one can't drop a column or a constraint in SQLite. The workaround for this is to recreate the original table omitting the corresponding constraint (or column). sqlalchemy-migrate library has recreate_table() method that implements this workaround, but it does it wrong: - information about unique constraints of a table is not retrieved. So if you have a table with one unique constraint and a migration adding another one you will end up with a table that has only the latter unique constraint, and the former will be lost - dropping of unique constraints is not supported at all The proper way to fix this is to provide a pull-request to sqlalchemy-migrate, but the project seems to be dead. So we can go on with monkey-patching of the lib at least for now. """ # this patch is needed to ensure that recreate_table() doesn't drop # existing unique constraints of the table when creating a new one helper_cls = sqlite.SQLiteHelper helper_cls.recreate_table = _recreate_table helper_cls._get_unique_constraints = _get_unique_constraints # this patch is needed to be able to drop existing unique constraints constraint_cls = sqlite.SQLiteConstraintDropper constraint_cls.visit_migrate_unique_constraint = \ _visit_migrate_unique_constraint constraint_cls.__bases__ = (ansisql.ANSIColumnDropper, sqlite.SQLiteConstraintGenerator) def db_sync(engine, abs_path, version=None, init_version=0, sanity_check=True): """Upgrade or downgrade a database. Function runs the upgrade() or downgrade() functions in change scripts. :param engine: SQLAlchemy engine instance for a given database :param abs_path: Absolute path to migrate repository. :param version: Database will upgrade/downgrade until this version. If None - database will update to the latest available version. :param init_version: Initial database version :param sanity_check: Require schema sanity checking for all tables """ if version is not None: try: version = int(version) except ValueError: raise exception.DbMigrationError( message=_("version should be an integer")) current_version = db_version(engine, abs_path, init_version) repository = _find_migrate_repo(abs_path) if sanity_check: _db_schema_sanity_check(engine) if version is None or version > current_version: return versioning_api.upgrade(engine, repository, version) else: return versioning_api.downgrade(engine, repository, version) def _db_schema_sanity_check(engine): """Ensure all database tables were created with required parameters. :param engine: SQLAlchemy engine instance for a given database """ if engine.name == 'mysql': onlyutf8_sql = ('SELECT TABLE_NAME,TABLE_COLLATION ' 'from information_schema.TABLES ' 'where TABLE_SCHEMA=%s and ' 'TABLE_COLLATION NOT LIKE "%%utf8%%"') table_names = [res[0] for res in engine.execute(onlyutf8_sql, engine.url.database)] if len(table_names) > 0: raise ValueError(_('Tables "%s" have non utf8 collation, ' 'please make sure all tables are CHARSET=utf8' ) % ','.join(table_names)) def db_version(engine, abs_path, init_version): """Show the current version of the repository. :param engine: SQLAlchemy engine instance for a given database :param abs_path: Absolute path to migrate repository :param version: Initial database version """ repository = _find_migrate_repo(abs_path) try: return versioning_api.db_version(engine, repository) except versioning_exceptions.DatabaseNotControlledError: meta = sqlalchemy.MetaData() meta.reflect(bind=engine) tables = meta.tables if len(tables) == 0 or 'alembic_version' in tables: db_version_control(engine, abs_path, version=init_version) return versioning_api.db_version(engine, repository) else: raise exception.DbMigrationError( message=_( "The database is not under version control, but has " "tables. Please stamp the current version of the schema " "manually.")) def db_version_control(engine, abs_path, version=None): """Mark a database as under this repository's version control. Once a database is under version control, schema changes should only be done via change scripts in this repository. :param engine: SQLAlchemy engine instance for a given database :param abs_path: Absolute path to migrate repository :param version: Initial database version """ repository = _find_migrate_repo(abs_path) versioning_api.version_control(engine, repository, version) return version def _find_migrate_repo(abs_path): """Get the project's change script repository :param abs_path: Absolute path to migrate repository """ if not os.path.exists(abs_path): raise exception.DbMigrationError("Path %s not found" % abs_path) return Repository(abs_path) glance-2014.1/glance/openstack/common/db/sqlalchemy/session.py0000664000175400017540000010450512323736226025477 0ustar jenkinsjenkins00000000000000# Copyright 2010 United States Government as represented by the # Administrator of the National Aeronautics and Space Administration. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """Session Handling for SQLAlchemy backend. Recommended ways to use sessions within this framework: * Don't use them explicitly; this is like running with ``AUTOCOMMIT=1``. `model_query()` will implicitly use a session when called without one supplied. This is the ideal situation because it will allow queries to be automatically retried if the database connection is interrupted. .. note:: Automatic retry will be enabled in a future patch. It is generally fine to issue several queries in a row like this. Even though they may be run in separate transactions and/or separate sessions, each one will see the data from the prior calls. If needed, undo- or rollback-like functionality should be handled at a logical level. For an example, look at the code around quotas and `reservation_rollback()`. Examples: .. code:: python def get_foo(context, foo): return (model_query(context, models.Foo). filter_by(foo=foo). first()) def update_foo(context, id, newfoo): (model_query(context, models.Foo). filter_by(id=id). update({'foo': newfoo})) def create_foo(context, values): foo_ref = models.Foo() foo_ref.update(values) foo_ref.save() return foo_ref * Within the scope of a single method, keep all the reads and writes within the context managed by a single session. In this way, the session's `__exit__` handler will take care of calling `flush()` and `commit()` for you. If using this approach, you should not explicitly call `flush()` or `commit()`. Any error within the context of the session will cause the session to emit a `ROLLBACK`. Database errors like `IntegrityError` will be raised in `session`'s `__exit__` handler, and any try/except within the context managed by `session` will not be triggered. And catching other non-database errors in the session will not trigger the ROLLBACK, so exception handlers should always be outside the session, unless the developer wants to do a partial commit on purpose. If the connection is dropped before this is possible, the database will implicitly roll back the transaction. .. note:: Statements in the session scope will not be automatically retried. If you create models within the session, they need to be added, but you do not need to call `model.save()`: .. code:: python def create_many_foo(context, foos): session = sessionmaker() with session.begin(): for foo in foos: foo_ref = models.Foo() foo_ref.update(foo) session.add(foo_ref) def update_bar(context, foo_id, newbar): session = sessionmaker() with session.begin(): foo_ref = (model_query(context, models.Foo, session). filter_by(id=foo_id). first()) (model_query(context, models.Bar, session). filter_by(id=foo_ref['bar_id']). update({'bar': newbar})) .. note:: `update_bar` is a trivially simple example of using ``with session.begin``. Whereas `create_many_foo` is a good example of when a transaction is needed, it is always best to use as few queries as possible. The two queries in `update_bar` can be better expressed using a single query which avoids the need for an explicit transaction. It can be expressed like so: .. code:: python def update_bar(context, foo_id, newbar): subq = (model_query(context, models.Foo.id). filter_by(id=foo_id). limit(1). subquery()) (model_query(context, models.Bar). filter_by(id=subq.as_scalar()). update({'bar': newbar})) For reference, this emits approximately the following SQL statement: .. code:: sql UPDATE bar SET bar = ${newbar} WHERE id=(SELECT bar_id FROM foo WHERE id = ${foo_id} LIMIT 1); .. note:: `create_duplicate_foo` is a trivially simple example of catching an exception while using ``with session.begin``. Here create two duplicate instances with same primary key, must catch the exception out of context managed by a single session: .. code:: python def create_duplicate_foo(context): foo1 = models.Foo() foo2 = models.Foo() foo1.id = foo2.id = 1 session = sessionmaker() try: with session.begin(): session.add(foo1) session.add(foo2) except exception.DBDuplicateEntry as e: handle_error(e) * Passing an active session between methods. Sessions should only be passed to private methods. The private method must use a subtransaction; otherwise SQLAlchemy will throw an error when you call `session.begin()` on an existing transaction. Public methods should not accept a session parameter and should not be involved in sessions within the caller's scope. Note that this incurs more overhead in SQLAlchemy than the above means due to nesting transactions, and it is not possible to implicitly retry failed database operations when using this approach. This also makes code somewhat more difficult to read and debug, because a single database transaction spans more than one method. Error handling becomes less clear in this situation. When this is needed for code clarity, it should be clearly documented. .. code:: python def myfunc(foo): session = sessionmaker() with session.begin(): # do some database things bar = _private_func(foo, session) return bar def _private_func(foo, session=None): if not session: session = sessionmaker() with session.begin(subtransaction=True): # do some other database things return bar There are some things which it is best to avoid: * Don't keep a transaction open any longer than necessary. This means that your ``with session.begin()`` block should be as short as possible, while still containing all the related calls for that transaction. * Avoid ``with_lockmode('UPDATE')`` when possible. In MySQL/InnoDB, when a ``SELECT ... FOR UPDATE`` query does not match any rows, it will take a gap-lock. This is a form of write-lock on the "gap" where no rows exist, and prevents any other writes to that space. This can effectively prevent any INSERT into a table by locking the gap at the end of the index. Similar problems will occur if the SELECT FOR UPDATE has an overly broad WHERE clause, or doesn't properly use an index. One idea proposed at ODS Fall '12 was to use a normal SELECT to test the number of rows matching a query, and if only one row is returned, then issue the SELECT FOR UPDATE. The better long-term solution is to use ``INSERT .. ON DUPLICATE KEY UPDATE``. However, this can not be done until the "deleted" columns are removed and proper UNIQUE constraints are added to the tables. Enabling soft deletes: * To use/enable soft-deletes, the `SoftDeleteMixin` must be added to your model class. For example: .. code:: python class NovaBase(models.SoftDeleteMixin, models.ModelBase): pass Efficient use of soft deletes: * There are two possible ways to mark a record as deleted: `model.soft_delete()` and `query.soft_delete()`. The `model.soft_delete()` method works with a single already-fetched entry. `query.soft_delete()` makes only one db request for all entries that correspond to the query. * In almost all cases you should use `query.soft_delete()`. Some examples: .. code:: python def soft_delete_bar(): count = model_query(BarModel).find(some_condition).soft_delete() if count == 0: raise Exception("0 entries were soft deleted") def complex_soft_delete_with_synchronization_bar(session=None): if session is None: session = sessionmaker() with session.begin(subtransactions=True): count = (model_query(BarModel). find(some_condition). soft_delete(synchronize_session=True)) # Here synchronize_session is required, because we # don't know what is going on in outer session. if count == 0: raise Exception("0 entries were soft deleted") * There is only one situation where `model.soft_delete()` is appropriate: when you fetch a single record, work with it, and mark it as deleted in the same transaction. .. code:: python def soft_delete_bar_model(): session = sessionmaker() with session.begin(): bar_ref = model_query(BarModel).find(some_condition).first() # Work with bar_ref bar_ref.soft_delete(session=session) However, if you need to work with all entries that correspond to query and then soft delete them you should use the `query.soft_delete()` method: .. code:: python def soft_delete_multi_models(): session = sessionmaker() with session.begin(): query = (model_query(BarModel, session=session). find(some_condition)) model_refs = query.all() # Work with model_refs query.soft_delete(synchronize_session=False) # synchronize_session=False should be set if there is no outer # session and these entries are not used after this. When working with many rows, it is very important to use query.soft_delete, which issues a single query. Using `model.soft_delete()`, as in the following example, is very inefficient. .. code:: python for bar_ref in bar_refs: bar_ref.soft_delete(session=session) # This will produce count(bar_refs) db requests. """ import functools import logging import re import time import six from sqlalchemy import exc as sqla_exc from sqlalchemy.interfaces import PoolListener import sqlalchemy.orm from sqlalchemy.pool import NullPool, StaticPool from sqlalchemy.sql.expression import literal_column from glance.openstack.common.db import exception from glance.openstack.common.gettextutils import _LE, _LW from glance.openstack.common import timeutils LOG = logging.getLogger(__name__) class SqliteForeignKeysListener(PoolListener): """Ensures that the foreign key constraints are enforced in SQLite. The foreign key constraints are disabled by default in SQLite, so the foreign key constraints will be enabled here for every database connection """ def connect(self, dbapi_con, con_record): dbapi_con.execute('pragma foreign_keys=ON') # note(boris-42): In current versions of DB backends unique constraint # violation messages follow the structure: # # sqlite: # 1 column - (IntegrityError) column c1 is not unique # N columns - (IntegrityError) column c1, c2, ..., N are not unique # # sqlite since 3.7.16: # 1 column - (IntegrityError) UNIQUE constraint failed: tbl.k1 # # N columns - (IntegrityError) UNIQUE constraint failed: tbl.k1, tbl.k2 # # postgres: # 1 column - (IntegrityError) duplicate key value violates unique # constraint "users_c1_key" # N columns - (IntegrityError) duplicate key value violates unique # constraint "name_of_our_constraint" # # mysql: # 1 column - (IntegrityError) (1062, "Duplicate entry 'value_of_c1' for key # 'c1'") # N columns - (IntegrityError) (1062, "Duplicate entry 'values joined # with -' for key 'name_of_our_constraint'") # # ibm_db_sa: # N columns - (IntegrityError) SQL0803N One or more values in the INSERT # statement, UPDATE statement, or foreign key update caused by a # DELETE statement are not valid because the primary key, unique # constraint or unique index identified by "2" constrains table # "NOVA.KEY_PAIRS" from having duplicate values for the index # key. _DUP_KEY_RE_DB = { "sqlite": (re.compile(r"^.*columns?([^)]+)(is|are)\s+not\s+unique$"), re.compile(r"^.*UNIQUE\s+constraint\s+failed:\s+(.+)$")), "postgresql": (re.compile(r"^.*duplicate\s+key.*\"([^\"]+)\"\s*\n.*$"),), "mysql": (re.compile(r"^.*\(1062,.*'([^\']+)'\"\)$"),), "ibm_db_sa": (re.compile(r"^.*SQL0803N.*$"),), } def _raise_if_duplicate_entry_error(integrity_error, engine_name): """Raise exception if two entries are duplicated. In this function will be raised DBDuplicateEntry exception if integrity error wrap unique constraint violation. """ def get_columns_from_uniq_cons_or_name(columns): # note(vsergeyev): UniqueConstraint name convention: "uniq_t0c10c2" # where `t` it is table name and columns `c1`, `c2` # are in UniqueConstraint. uniqbase = "uniq_" if not columns.startswith(uniqbase): if engine_name == "postgresql": return [columns[columns.index("_") + 1:columns.rindex("_")]] return [columns] return columns[len(uniqbase):].split("0")[1:] if engine_name not in ["ibm_db_sa", "mysql", "sqlite", "postgresql"]: return # FIXME(johannes): The usage of the .message attribute has been # deprecated since Python 2.6. However, the exceptions raised by # SQLAlchemy can differ when using unicode() and accessing .message. # An audit across all three supported engines will be necessary to # ensure there are no regressions. for pattern in _DUP_KEY_RE_DB[engine_name]: match = pattern.match(integrity_error.message) if match: break else: return # NOTE(mriedem): The ibm_db_sa integrity error message doesn't provide the # columns so we have to omit that from the DBDuplicateEntry error. columns = '' if engine_name != 'ibm_db_sa': columns = match.group(1) if engine_name == "sqlite": columns = [c.split('.')[-1] for c in columns.strip().split(", ")] else: columns = get_columns_from_uniq_cons_or_name(columns) raise exception.DBDuplicateEntry(columns, integrity_error) # NOTE(comstud): In current versions of DB backends, Deadlock violation # messages follow the structure: # # mysql: # (OperationalError) (1213, 'Deadlock found when trying to get lock; try ' # 'restarting transaction') _DEADLOCK_RE_DB = { "mysql": re.compile(r"^.*\(1213, 'Deadlock.*") } def _raise_if_deadlock_error(operational_error, engine_name): """Raise exception on deadlock condition. Raise DBDeadlock exception if OperationalError contains a Deadlock condition. """ re = _DEADLOCK_RE_DB.get(engine_name) if re is None: return # FIXME(johannes): The usage of the .message attribute has been # deprecated since Python 2.6. However, the exceptions raised by # SQLAlchemy can differ when using unicode() and accessing .message. # An audit across all three supported engines will be necessary to # ensure there are no regressions. m = re.match(operational_error.message) if not m: return raise exception.DBDeadlock(operational_error) def _wrap_db_error(f): @functools.wraps(f) def _wrap(self, *args, **kwargs): try: assert issubclass( self.__class__, sqlalchemy.orm.session.Session ), ('_wrap_db_error() can only be applied to methods of ' 'subclasses of sqlalchemy.orm.session.Session.') return f(self, *args, **kwargs) except UnicodeEncodeError: raise exception.DBInvalidUnicodeParameter() except sqla_exc.OperationalError as e: _raise_if_db_connection_lost(e, self.bind) _raise_if_deadlock_error(e, self.bind.dialect.name) # NOTE(comstud): A lot of code is checking for OperationalError # so let's not wrap it for now. raise # note(boris-42): We should catch unique constraint violation and # wrap it by our own DBDuplicateEntry exception. Unique constraint # violation is wrapped by IntegrityError. except sqla_exc.IntegrityError as e: # note(boris-42): SqlAlchemy doesn't unify errors from different # DBs so we must do this. Also in some tables (for example # instance_types) there are more than one unique constraint. This # means we should get names of columns, which values violate # unique constraint, from error message. _raise_if_duplicate_entry_error(e, self.bind.dialect.name) raise exception.DBError(e) except Exception as e: LOG.exception(_LE('DB exception wrapped.')) raise exception.DBError(e) return _wrap def _synchronous_switch_listener(dbapi_conn, connection_rec): """Switch sqlite connections to non-synchronous mode.""" dbapi_conn.execute("PRAGMA synchronous = OFF") def _add_regexp_listener(dbapi_con, con_record): """Add REGEXP function to sqlite connections.""" def regexp(expr, item): reg = re.compile(expr) return reg.search(six.text_type(item)) is not None dbapi_con.create_function('regexp', 2, regexp) def _thread_yield(dbapi_con, con_record): """Ensure other greenthreads get a chance to be executed. If we use eventlet.monkey_patch(), eventlet.greenthread.sleep(0) will execute instead of time.sleep(0). Force a context switch. With common database backends (eg MySQLdb and sqlite), there is no implicit yield caused by network I/O since they are implemented by C libraries that eventlet cannot monkey patch. """ time.sleep(0) def _ping_listener(engine, dbapi_conn, connection_rec, connection_proxy): """Ensures that MySQL and DB2 connections are alive. Borrowed from: http://groups.google.com/group/sqlalchemy/msg/a4ce563d802c929f """ cursor = dbapi_conn.cursor() try: ping_sql = 'select 1' if engine.name == 'ibm_db_sa': # DB2 requires a table expression ping_sql = 'select 1 from (values (1)) AS t1' cursor.execute(ping_sql) except Exception as ex: if engine.dialect.is_disconnect(ex, dbapi_conn, cursor): msg = _LW('Database server has gone away: %s') % ex LOG.warning(msg) # if the database server has gone away, all connections in the pool # have become invalid and we can safely close all of them here, # rather than waste time on checking of every single connection engine.dispose() # this will be handled by SQLAlchemy and will force it to create # a new connection and retry the original action raise sqla_exc.DisconnectionError(msg) else: raise def _set_session_sql_mode(dbapi_con, connection_rec, sql_mode=None): """Set the sql_mode session variable. MySQL supports several server modes. The default is None, but sessions may choose to enable server modes like TRADITIONAL, ANSI, several STRICT_* modes and others. Note: passing in '' (empty string) for sql_mode clears the SQL mode for the session, overriding a potentially set server default. """ cursor = dbapi_con.cursor() cursor.execute("SET SESSION sql_mode = %s", [sql_mode]) def _mysql_get_effective_sql_mode(engine): """Returns the effective SQL mode for connections from the engine pool. Returns ``None`` if the mode isn't available, otherwise returns the mode. """ # Get the real effective SQL mode. Even when unset by # our own config, the server may still be operating in a specific # SQL mode as set by the server configuration. # Also note that the checkout listener will be called on execute to # set the mode if it's registered. row = engine.execute("SHOW VARIABLES LIKE 'sql_mode'").fetchone() if row is None: return return row[1] def _mysql_check_effective_sql_mode(engine): """Logs a message based on the effective SQL mode for MySQL connections.""" realmode = _mysql_get_effective_sql_mode(engine) if realmode is None: LOG.warning(_LW('Unable to detect effective SQL mode')) return LOG.debug('MySQL server mode set to %s', realmode) # 'TRADITIONAL' mode enables several other modes, so # we need a substring match here if not ('TRADITIONAL' in realmode.upper() or 'STRICT_ALL_TABLES' in realmode.upper()): LOG.warning(_LW("MySQL SQL mode is '%s', " "consider enabling TRADITIONAL or STRICT_ALL_TABLES"), realmode) def _mysql_set_mode_callback(engine, sql_mode): if sql_mode is not None: mode_callback = functools.partial(_set_session_sql_mode, sql_mode=sql_mode) sqlalchemy.event.listen(engine, 'connect', mode_callback) _mysql_check_effective_sql_mode(engine) def _is_db_connection_error(args): """Return True if error in connecting to db.""" # NOTE(adam_g): This is currently MySQL specific and needs to be extended # to support Postgres and others. # For the db2, the error code is -30081 since the db2 is still not ready conn_err_codes = ('2002', '2003', '2006', '2013', '-30081') for err_code in conn_err_codes: if args.find(err_code) != -1: return True return False def _raise_if_db_connection_lost(error, engine): # NOTE(vsergeyev): Function is_disconnect(e, connection, cursor) # requires connection and cursor in incoming parameters, # but we have no possibility to create connection if DB # is not available, so in such case reconnect fails. # But is_disconnect() ignores these parameters, so it # makes sense to pass to function None as placeholder # instead of connection and cursor. if engine.dialect.is_disconnect(error, None, None): raise exception.DBConnectionError(error) def create_engine(sql_connection, sqlite_fk=False, mysql_sql_mode=None, idle_timeout=3600, connection_debug=0, max_pool_size=None, max_overflow=None, pool_timeout=None, sqlite_synchronous=True, connection_trace=False, max_retries=10, retry_interval=10): """Return a new SQLAlchemy engine.""" connection_dict = sqlalchemy.engine.url.make_url(sql_connection) engine_args = { "pool_recycle": idle_timeout, 'convert_unicode': True, } logger = logging.getLogger('sqlalchemy.engine') # Map SQL debug level to Python log level if connection_debug >= 100: logger.setLevel(logging.DEBUG) elif connection_debug >= 50: logger.setLevel(logging.INFO) else: logger.setLevel(logging.WARNING) if "sqlite" in connection_dict.drivername: if sqlite_fk: engine_args["listeners"] = [SqliteForeignKeysListener()] engine_args["poolclass"] = NullPool if sql_connection == "sqlite://": engine_args["poolclass"] = StaticPool engine_args["connect_args"] = {'check_same_thread': False} else: if max_pool_size is not None: engine_args['pool_size'] = max_pool_size if max_overflow is not None: engine_args['max_overflow'] = max_overflow if pool_timeout is not None: engine_args['pool_timeout'] = pool_timeout engine = sqlalchemy.create_engine(sql_connection, **engine_args) sqlalchemy.event.listen(engine, 'checkin', _thread_yield) if engine.name in ['mysql', 'ibm_db_sa']: ping_callback = functools.partial(_ping_listener, engine) sqlalchemy.event.listen(engine, 'checkout', ping_callback) if engine.name == 'mysql': if mysql_sql_mode: _mysql_set_mode_callback(engine, mysql_sql_mode) elif 'sqlite' in connection_dict.drivername: if not sqlite_synchronous: sqlalchemy.event.listen(engine, 'connect', _synchronous_switch_listener) sqlalchemy.event.listen(engine, 'connect', _add_regexp_listener) if connection_trace and engine.dialect.dbapi.__name__ == 'MySQLdb': _patch_mysqldb_with_stacktrace_comments() try: engine.connect() except sqla_exc.OperationalError as e: if not _is_db_connection_error(e.args[0]): raise remaining = max_retries if remaining == -1: remaining = 'infinite' while True: msg = _LW('SQL connection failed. %s attempts left.') LOG.warning(msg % remaining) if remaining != 'infinite': remaining -= 1 time.sleep(retry_interval) try: engine.connect() break except sqla_exc.OperationalError as e: if (remaining != 'infinite' and remaining == 0) or \ not _is_db_connection_error(e.args[0]): raise return engine class Query(sqlalchemy.orm.query.Query): """Subclass of sqlalchemy.query with soft_delete() method.""" def soft_delete(self, synchronize_session='evaluate'): return self.update({'deleted': literal_column('id'), 'updated_at': literal_column('updated_at'), 'deleted_at': timeutils.utcnow()}, synchronize_session=synchronize_session) class Session(sqlalchemy.orm.session.Session): """Custom Session class to avoid SqlAlchemy Session monkey patching.""" @_wrap_db_error def query(self, *args, **kwargs): return super(Session, self).query(*args, **kwargs) @_wrap_db_error def flush(self, *args, **kwargs): return super(Session, self).flush(*args, **kwargs) @_wrap_db_error def execute(self, *args, **kwargs): return super(Session, self).execute(*args, **kwargs) def get_maker(engine, autocommit=True, expire_on_commit=False): """Return a SQLAlchemy sessionmaker using the given engine.""" return sqlalchemy.orm.sessionmaker(bind=engine, class_=Session, autocommit=autocommit, expire_on_commit=expire_on_commit, query_cls=Query) def _patch_mysqldb_with_stacktrace_comments(): """Adds current stack trace as a comment in queries. Patches MySQLdb.cursors.BaseCursor._do_query. """ import MySQLdb.cursors import traceback old_mysql_do_query = MySQLdb.cursors.BaseCursor._do_query def _do_query(self, q): stack = '' for filename, line, method, function in traceback.extract_stack(): # exclude various common things from trace if filename.endswith('session.py') and method == '_do_query': continue if filename.endswith('api.py') and method == 'wrapper': continue if filename.endswith('utils.py') and method == '_inner': continue if filename.endswith('exception.py') and method == '_wrap': continue # db/api is just a wrapper around db/sqlalchemy/api if filename.endswith('db/api.py'): continue # only trace inside glance index = filename.rfind('glance') if index == -1: continue stack += "File:%s:%s Method:%s() Line:%s | " \ % (filename[index:], line, method, function) # strip trailing " | " from stack if stack: stack = stack[:-3] qq = "%s /* %s */" % (q, stack) else: qq = q old_mysql_do_query(self, qq) setattr(MySQLdb.cursors.BaseCursor, '_do_query', _do_query) class EngineFacade(object): """A helper class for removing of global engine instances from glance.db. As a library, glance.db can't decide where to store/when to create engine and sessionmaker instances, so this must be left for a target application. On the other hand, in order to simplify the adoption of glance.db changes, we'll provide a helper class, which creates engine and sessionmaker on its instantiation and provides get_engine()/get_session() methods that are compatible with corresponding utility functions that currently exist in target projects, e.g. in Nova. engine/sessionmaker instances will still be global (and they are meant to be global), but they will be stored in the app context, rather that in the glance.db context. Note: using of this helper is completely optional and you are encouraged to integrate engine/sessionmaker instances into your apps any way you like (e.g. one might want to bind a session to a request context). Two important things to remember: 1. An Engine instance is effectively a pool of DB connections, so it's meant to be shared (and it's thread-safe). 2. A Session instance is not meant to be shared and represents a DB transactional context (i.e. it's not thread-safe). sessionmaker is a factory of sessions. """ def __init__(self, sql_connection, sqlite_fk=False, autocommit=True, expire_on_commit=False, **kwargs): """Initialize engine and sessionmaker instances. :param sqlite_fk: enable foreign keys in SQLite :type sqlite_fk: bool :param autocommit: use autocommit mode for created Session instances :type autocommit: bool :param expire_on_commit: expire session objects on commit :type expire_on_commit: bool Keyword arguments: :keyword mysql_sql_mode: the SQL mode to be used for MySQL sessions. (defaults to TRADITIONAL) :keyword idle_timeout: timeout before idle sql connections are reaped (defaults to 3600) :keyword connection_debug: verbosity of SQL debugging information. 0=None, 100=Everything (defaults to 0) :keyword max_pool_size: maximum number of SQL connections to keep open in a pool (defaults to SQLAlchemy settings) :keyword max_overflow: if set, use this value for max_overflow with sqlalchemy (defaults to SQLAlchemy settings) :keyword pool_timeout: if set, use this value for pool_timeout with sqlalchemy (defaults to SQLAlchemy settings) :keyword sqlite_synchronous: if True, SQLite uses synchronous mode (defaults to True) :keyword connection_trace: add python stack traces to SQL as comment strings (defaults to False) :keyword max_retries: maximum db connection retries during startup. (setting -1 implies an infinite retry count) (defaults to 10) :keyword retry_interval: interval between retries of opening a sql connection (defaults to 10) """ super(EngineFacade, self).__init__() self._engine = create_engine( sql_connection=sql_connection, sqlite_fk=sqlite_fk, mysql_sql_mode=kwargs.get('mysql_sql_mode', 'TRADITIONAL'), idle_timeout=kwargs.get('idle_timeout', 3600), connection_debug=kwargs.get('connection_debug', 0), max_pool_size=kwargs.get('max_pool_size'), max_overflow=kwargs.get('max_overflow'), pool_timeout=kwargs.get('pool_timeout'), sqlite_synchronous=kwargs.get('sqlite_synchronous', True), connection_trace=kwargs.get('connection_trace', False), max_retries=kwargs.get('max_retries', 10), retry_interval=kwargs.get('retry_interval', 10)) self._session_maker = get_maker( engine=self._engine, autocommit=autocommit, expire_on_commit=expire_on_commit) def get_engine(self): """Get the engine instance (note, that it's shared).""" return self._engine def get_session(self, **kwargs): """Get a Session instance. If passed, keyword arguments values override the ones used when the sessionmaker instance was created. :keyword autocommit: use autocommit mode for created Session instances :type autocommit: bool :keyword expire_on_commit: expire session objects on commit :type expire_on_commit: bool """ for arg in kwargs: if arg not in ('autocommit', 'expire_on_commit'): del kwargs[arg] return self._session_maker(**kwargs) @classmethod def from_config(cls, connection_string, conf, sqlite_fk=False, autocommit=True, expire_on_commit=False): """Initialize EngineFacade using oslo.config config instance options. :param connection_string: SQLAlchemy connection string :type connection_string: string :param conf: oslo.config config instance :type conf: oslo.config.cfg.ConfigOpts :param sqlite_fk: enable foreign keys in SQLite :type sqlite_fk: bool :param autocommit: use autocommit mode for created Session instances :type autocommit: bool :param expire_on_commit: expire session objects on commit :type expire_on_commit: bool """ return cls(sql_connection=connection_string, sqlite_fk=sqlite_fk, autocommit=autocommit, expire_on_commit=expire_on_commit, **dict(conf.database.items())) glance-2014.1/glance/openstack/common/db/sqlalchemy/test_migrations.conf0000664000175400017540000000044112323736226027516 0ustar jenkinsjenkins00000000000000[DEFAULT] # Set up any number of migration data stores you want, one # The "name" used in the test is the config variable key. #sqlite=sqlite:///test_migrations.db sqlite=sqlite:// #mysql=mysql://root:@localhost/test_migrations #postgresql=postgresql://user:pass@localhost/test_migrations glance-2014.1/glance/openstack/common/db/sqlalchemy/utils.py0000664000175400017540000005733412323736226025163 0ustar jenkinsjenkins00000000000000# Copyright 2010 United States Government as represented by the # Administrator of the National Aeronautics and Space Administration. # Copyright 2010-2011 OpenStack Foundation. # Copyright 2012 Justin Santa Barbara # 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 re import sqlalchemy from sqlalchemy import Boolean from sqlalchemy import CheckConstraint from sqlalchemy import Column from sqlalchemy.engine import reflection from sqlalchemy.ext.compiler import compiles from sqlalchemy import func from sqlalchemy import Index from sqlalchemy import Integer from sqlalchemy import MetaData from sqlalchemy import or_ from sqlalchemy.sql.expression import literal_column from sqlalchemy.sql.expression import UpdateBase from sqlalchemy import String from sqlalchemy import Table from sqlalchemy.types import NullType from glance.openstack.common import context as request_context from glance.openstack.common.db.sqlalchemy import models from glance.openstack.common.gettextutils import _, _LI, _LW from glance.openstack.common import timeutils LOG = logging.getLogger(__name__) _DBURL_REGEX = re.compile(r"[^:]+://([^:]+):([^@]+)@.+") def sanitize_db_url(url): match = _DBURL_REGEX.match(url) if match: return '%s****:****%s' % (url[:match.start(1)], url[match.end(2):]) return url class InvalidSortKey(Exception): message = _("Sort key supplied was not valid.") # copy from glance/db/sqlalchemy/api.py def paginate_query(query, model, limit, sort_keys, marker=None, sort_dir=None, sort_dirs=None): """Returns a query with sorting / pagination criteria added. Pagination works by requiring a unique sort_key, specified by sort_keys. (If sort_keys is not unique, then we risk looping through values.) We use the last row in the previous page as the 'marker' for pagination. So we must return values that follow the passed marker in the order. With a single-valued sort_key, this would be easy: sort_key > X. With a compound-values sort_key, (k1, k2, k3) we must do this to repeat the lexicographical ordering: (k1 > X1) or (k1 == X1 && k2 > X2) or (k1 == X1 && k2 == X2 && k3 > X3) We also have to cope with different sort_directions. Typically, the id of the last row is used as the client-facing pagination marker, then the actual marker object must be fetched from the db and passed in to us as marker. :param query: the query object to which we should add paging/sorting :param model: the ORM model class :param limit: maximum number of items to return :param sort_keys: array of attributes by which results should be sorted :param marker: the last item of the previous page; we returns the next results after this value. :param sort_dir: direction in which results should be sorted (asc, desc) :param sort_dirs: per-column array of sort_dirs, corresponding to sort_keys :rtype: sqlalchemy.orm.query.Query :return: The query with sorting/pagination added. """ if 'id' not in sort_keys: # TODO(justinsb): If this ever gives a false-positive, check # the actual primary key, rather than assuming its id LOG.warning(_LW('Id not in sort_keys; is sort_keys unique?')) assert(not (sort_dir and sort_dirs)) # Default the sort direction to ascending if sort_dirs is None and sort_dir is None: sort_dir = 'asc' # Ensure a per-column sort direction if sort_dirs is None: sort_dirs = [sort_dir for _sort_key in sort_keys] assert(len(sort_dirs) == len(sort_keys)) # Add sorting for current_sort_key, current_sort_dir in zip(sort_keys, sort_dirs): try: sort_dir_func = { 'asc': sqlalchemy.asc, 'desc': sqlalchemy.desc, }[current_sort_dir] except KeyError: raise ValueError(_("Unknown sort direction, " "must be 'desc' or 'asc'")) try: sort_key_attr = getattr(model, current_sort_key) except AttributeError: raise InvalidSortKey() query = query.order_by(sort_dir_func(sort_key_attr)) # Add pagination if marker is not None: marker_values = [] for sort_key in sort_keys: v = getattr(marker, sort_key) marker_values.append(v) # Build up an array of sort criteria as in the docstring criteria_list = [] for i in range(len(sort_keys)): crit_attrs = [] for j in range(i): model_attr = getattr(model, sort_keys[j]) crit_attrs.append((model_attr == marker_values[j])) model_attr = getattr(model, sort_keys[i]) if sort_dirs[i] == 'desc': crit_attrs.append((model_attr < marker_values[i])) else: crit_attrs.append((model_attr > marker_values[i])) criteria = sqlalchemy.sql.and_(*crit_attrs) criteria_list.append(criteria) f = sqlalchemy.sql.or_(*criteria_list) query = query.filter(f) if limit is not None: query = query.limit(limit) return query def _read_deleted_filter(query, db_model, read_deleted): if 'deleted' not in db_model.__table__.columns: raise ValueError(_("There is no `deleted` column in `%s` table. " "Project doesn't use soft-deleted feature.") % db_model.__name__) default_deleted_value = db_model.__table__.c.deleted.default.arg if read_deleted == 'no': query = query.filter(db_model.deleted == default_deleted_value) elif read_deleted == 'yes': pass # omit the filter to include deleted and active elif read_deleted == 'only': query = query.filter(db_model.deleted != default_deleted_value) else: raise ValueError(_("Unrecognized read_deleted value '%s'") % read_deleted) return query def _project_filter(query, db_model, context, project_only): if project_only and 'project_id' not in db_model.__table__.columns: raise ValueError(_("There is no `project_id` column in `%s` table.") % db_model.__name__) if request_context.is_user_context(context) and project_only: if project_only == 'allow_none': is_none = None query = query.filter(or_(db_model.project_id == context.project_id, db_model.project_id == is_none)) else: query = query.filter(db_model.project_id == context.project_id) return query def model_query(context, model, session, args=None, project_only=False, read_deleted=None): """Query helper that accounts for context's `read_deleted` field. :param context: context to query under :param model: Model to query. Must be a subclass of ModelBase. :type model: models.ModelBase :param session: The session to use. :type session: sqlalchemy.orm.session.Session :param args: Arguments to query. If None - model is used. :type args: tuple :param project_only: If present and context is user-type, then restrict query to match the context's project_id. If set to 'allow_none', restriction includes project_id = None. :type project_only: bool :param read_deleted: If present, overrides context's read_deleted field. :type read_deleted: bool Usage: ..code:: python result = (utils.model_query(context, models.Instance, session=session) .filter_by(uuid=instance_uuid) .all()) query = utils.model_query( context, Node, session=session, args=(func.count(Node.id), func.sum(Node.ram)) ).filter_by(project_id=project_id) """ if not read_deleted: if hasattr(context, 'read_deleted'): # NOTE(viktors): some projects use `read_deleted` attribute in # their contexts instead of `show_deleted`. read_deleted = context.read_deleted else: read_deleted = context.show_deleted if not issubclass(model, models.ModelBase): raise TypeError(_("model should be a subclass of ModelBase")) query = session.query(model) if not args else session.query(*args) query = _read_deleted_filter(query, model, read_deleted) query = _project_filter(query, model, context, project_only) return query def get_table(engine, name): """Returns an sqlalchemy table dynamically from db. Needed because the models don't work for us in migrations as models will be far out of sync with the current data. """ metadata = MetaData() metadata.bind = engine return Table(name, metadata, autoload=True) class InsertFromSelect(UpdateBase): """Form the base for `INSERT INTO table (SELECT ... )` statement.""" def __init__(self, table, select): self.table = table self.select = select @compiles(InsertFromSelect) def visit_insert_from_select(element, compiler, **kw): """Form the `INSERT INTO table (SELECT ... )` statement.""" return "INSERT INTO %s %s" % ( compiler.process(element.table, asfrom=True), compiler.process(element.select)) class ColumnError(Exception): """Error raised when no column or an invalid column is found.""" def _get_not_supported_column(col_name_col_instance, column_name): try: column = col_name_col_instance[column_name] except KeyError: msg = _("Please specify column %s in col_name_col_instance " "param. It is required because column has unsupported " "type by sqlite).") raise ColumnError(msg % column_name) if not isinstance(column, Column): msg = _("col_name_col_instance param has wrong type of " "column instance for column %s It should be instance " "of sqlalchemy.Column.") raise ColumnError(msg % column_name) return column def drop_unique_constraint(migrate_engine, table_name, uc_name, *columns, **col_name_col_instance): """Drop unique constraint from table. DEPRECATED: this function is deprecated and will be removed from glance.db in a few releases. Please use UniqueConstraint.drop() method directly for sqlalchemy-migrate migration scripts. This method drops UC from table and works for mysql, postgresql and sqlite. In mysql and postgresql we are able to use "alter table" construction. Sqlalchemy doesn't support some sqlite column types and replaces their type with NullType in metadata. We process these columns and replace NullType with the correct column type. :param migrate_engine: sqlalchemy engine :param table_name: name of table that contains uniq constraint. :param uc_name: name of uniq constraint that will be dropped. :param columns: columns that are in uniq constraint. :param col_name_col_instance: contains pair column_name=column_instance. column_instance is instance of Column. These params are required only for columns that have unsupported types by sqlite. For example BigInteger. """ from migrate.changeset import UniqueConstraint meta = MetaData() meta.bind = migrate_engine t = Table(table_name, meta, autoload=True) if migrate_engine.name == "sqlite": override_cols = [ _get_not_supported_column(col_name_col_instance, col.name) for col in t.columns if isinstance(col.type, NullType) ] for col in override_cols: t.columns.replace(col) uc = UniqueConstraint(*columns, table=t, name=uc_name) uc.drop() def drop_old_duplicate_entries_from_table(migrate_engine, table_name, use_soft_delete, *uc_column_names): """Drop all old rows having the same values for columns in uc_columns. This method drop (or mark ad `deleted` if use_soft_delete is True) old duplicate rows form table with name `table_name`. :param migrate_engine: Sqlalchemy engine :param table_name: Table with duplicates :param use_soft_delete: If True - values will be marked as `deleted`, if False - values will be removed from table :param uc_column_names: Unique constraint columns """ meta = MetaData() meta.bind = migrate_engine table = Table(table_name, meta, autoload=True) columns_for_group_by = [table.c[name] for name in uc_column_names] columns_for_select = [func.max(table.c.id)] columns_for_select.extend(columns_for_group_by) duplicated_rows_select = sqlalchemy.sql.select( columns_for_select, group_by=columns_for_group_by, having=func.count(table.c.id) > 1) for row in migrate_engine.execute(duplicated_rows_select): # NOTE(boris-42): Do not remove row that has the biggest ID. delete_condition = table.c.id != row[0] is_none = None # workaround for pyflakes delete_condition &= table.c.deleted_at == is_none for name in uc_column_names: delete_condition &= table.c[name] == row[name] rows_to_delete_select = sqlalchemy.sql.select( [table.c.id]).where(delete_condition) for row in migrate_engine.execute(rows_to_delete_select).fetchall(): LOG.info(_LI("Deleting duplicated row with id: %(id)s from table: " "%(table)s") % dict(id=row[0], table=table_name)) if use_soft_delete: delete_statement = table.update().\ where(delete_condition).\ values({ 'deleted': literal_column('id'), 'updated_at': literal_column('updated_at'), 'deleted_at': timeutils.utcnow() }) else: delete_statement = table.delete().where(delete_condition) migrate_engine.execute(delete_statement) def _get_default_deleted_value(table): if isinstance(table.c.id.type, Integer): return 0 if isinstance(table.c.id.type, String): return "" raise ColumnError(_("Unsupported id columns type")) def _restore_indexes_on_deleted_columns(migrate_engine, table_name, indexes): table = get_table(migrate_engine, table_name) insp = reflection.Inspector.from_engine(migrate_engine) real_indexes = insp.get_indexes(table_name) existing_index_names = dict( [(index['name'], index['column_names']) for index in real_indexes]) # NOTE(boris-42): Restore indexes on `deleted` column for index in indexes: if 'deleted' not in index['column_names']: continue name = index['name'] if name in existing_index_names: column_names = [table.c[c] for c in existing_index_names[name]] old_index = Index(name, *column_names, unique=index["unique"]) old_index.drop(migrate_engine) column_names = [table.c[c] for c in index['column_names']] new_index = Index(index["name"], *column_names, unique=index["unique"]) new_index.create(migrate_engine) def change_deleted_column_type_to_boolean(migrate_engine, table_name, **col_name_col_instance): if migrate_engine.name == "sqlite": return _change_deleted_column_type_to_boolean_sqlite( migrate_engine, table_name, **col_name_col_instance) insp = reflection.Inspector.from_engine(migrate_engine) indexes = insp.get_indexes(table_name) table = get_table(migrate_engine, table_name) old_deleted = Column('old_deleted', Boolean, default=False) old_deleted.create(table, populate_default=False) table.update().\ where(table.c.deleted == table.c.id).\ values(old_deleted=True).\ execute() table.c.deleted.drop() table.c.old_deleted.alter(name="deleted") _restore_indexes_on_deleted_columns(migrate_engine, table_name, indexes) def _change_deleted_column_type_to_boolean_sqlite(migrate_engine, table_name, **col_name_col_instance): insp = reflection.Inspector.from_engine(migrate_engine) table = get_table(migrate_engine, table_name) columns = [] for column in table.columns: column_copy = None if column.name != "deleted": if isinstance(column.type, NullType): column_copy = _get_not_supported_column(col_name_col_instance, column.name) else: column_copy = column.copy() else: column_copy = Column('deleted', Boolean, default=0) columns.append(column_copy) constraints = [constraint.copy() for constraint in table.constraints] meta = table.metadata new_table = Table(table_name + "__tmp__", meta, *(columns + constraints)) new_table.create() indexes = [] for index in insp.get_indexes(table_name): column_names = [new_table.c[c] for c in index['column_names']] indexes.append(Index(index["name"], *column_names, unique=index["unique"])) c_select = [] for c in table.c: if c.name != "deleted": c_select.append(c) else: c_select.append(table.c.deleted == table.c.id) ins = InsertFromSelect(new_table, sqlalchemy.sql.select(c_select)) migrate_engine.execute(ins) table.drop() [index.create(migrate_engine) for index in indexes] new_table.rename(table_name) new_table.update().\ where(new_table.c.deleted == new_table.c.id).\ values(deleted=True).\ execute() def change_deleted_column_type_to_id_type(migrate_engine, table_name, **col_name_col_instance): if migrate_engine.name == "sqlite": return _change_deleted_column_type_to_id_type_sqlite( migrate_engine, table_name, **col_name_col_instance) insp = reflection.Inspector.from_engine(migrate_engine) indexes = insp.get_indexes(table_name) table = get_table(migrate_engine, table_name) new_deleted = Column('new_deleted', table.c.id.type, default=_get_default_deleted_value(table)) new_deleted.create(table, populate_default=True) deleted = True # workaround for pyflakes table.update().\ where(table.c.deleted == deleted).\ values(new_deleted=table.c.id).\ execute() table.c.deleted.drop() table.c.new_deleted.alter(name="deleted") _restore_indexes_on_deleted_columns(migrate_engine, table_name, indexes) def _change_deleted_column_type_to_id_type_sqlite(migrate_engine, table_name, **col_name_col_instance): # NOTE(boris-42): sqlaclhemy-migrate can't drop column with check # constraints in sqlite DB and our `deleted` column has # 2 check constraints. So there is only one way to remove # these constraints: # 1) Create new table with the same columns, constraints # and indexes. (except deleted column). # 2) Copy all data from old to new table. # 3) Drop old table. # 4) Rename new table to old table name. insp = reflection.Inspector.from_engine(migrate_engine) meta = MetaData(bind=migrate_engine) table = Table(table_name, meta, autoload=True) default_deleted_value = _get_default_deleted_value(table) columns = [] for column in table.columns: column_copy = None if column.name != "deleted": if isinstance(column.type, NullType): column_copy = _get_not_supported_column(col_name_col_instance, column.name) else: column_copy = column.copy() else: column_copy = Column('deleted', table.c.id.type, default=default_deleted_value) columns.append(column_copy) def is_deleted_column_constraint(constraint): # NOTE(boris-42): There is no other way to check is CheckConstraint # associated with deleted column. if not isinstance(constraint, CheckConstraint): return False sqltext = str(constraint.sqltext) return (sqltext.endswith("deleted in (0, 1)") or sqltext.endswith("deleted IN (:deleted_1, :deleted_2)")) constraints = [] for constraint in table.constraints: if not is_deleted_column_constraint(constraint): constraints.append(constraint.copy()) new_table = Table(table_name + "__tmp__", meta, *(columns + constraints)) new_table.create() indexes = [] for index in insp.get_indexes(table_name): column_names = [new_table.c[c] for c in index['column_names']] indexes.append(Index(index["name"], *column_names, unique=index["unique"])) ins = InsertFromSelect(new_table, table.select()) migrate_engine.execute(ins) table.drop() [index.create(migrate_engine) for index in indexes] new_table.rename(table_name) deleted = True # workaround for pyflakes new_table.update().\ where(new_table.c.deleted == deleted).\ values(deleted=new_table.c.id).\ execute() # NOTE(boris-42): Fix value of deleted column: False -> "" or 0. deleted = False # workaround for pyflakes new_table.update().\ where(new_table.c.deleted == deleted).\ values(deleted=default_deleted_value).\ execute() def get_connect_string(backend, database, user=None, passwd=None): """Get database connection Try to get a connection with a very specific set of values, if we get these then we'll run the tests, otherwise they are skipped """ args = {'backend': backend, 'user': user, 'passwd': passwd, 'database': database} if backend == 'sqlite': template = '%(backend)s:///%(database)s' else: template = "%(backend)s://%(user)s:%(passwd)s@localhost/%(database)s" return template % args def is_backend_avail(backend, database, user=None, passwd=None): try: connect_uri = get_connect_string(backend=backend, database=database, user=user, passwd=passwd) engine = sqlalchemy.create_engine(connect_uri) connection = engine.connect() except Exception: # intentionally catch all to handle exceptions even if we don't # have any backend code loaded. return False else: connection.close() engine.dispose() return True def get_db_connection_info(conn_pieces): database = conn_pieces.path.strip('/') loc_pieces = conn_pieces.netloc.split('@') host = loc_pieces[1] auth_pieces = loc_pieces[0].split(':') user = auth_pieces[0] password = "" if len(auth_pieces) > 1: password = auth_pieces[1].strip() return (user, password, database, host) glance-2014.1/glance/openstack/common/db/sqlalchemy/provision.py0000664000175400017540000001147112323736226026043 0ustar jenkinsjenkins00000000000000# Copyright 2013 Mirantis.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. """Provision test environment for specific DB backends""" import argparse import logging import os import random import string from six import moves import sqlalchemy from glance.openstack.common.db import exception as exc LOG = logging.getLogger(__name__) def get_engine(uri): """Engine creation Call the function without arguments to get admin connection. Admin connection required to create temporary user and database for each particular test. Otherwise use existing connection to recreate connection to the temporary database. """ return sqlalchemy.create_engine(uri, poolclass=sqlalchemy.pool.NullPool) def _execute_sql(engine, sql, driver): """Initialize connection, execute sql query and close it.""" try: with engine.connect() as conn: if driver == 'postgresql': conn.connection.set_isolation_level(0) for s in sql: conn.execute(s) except sqlalchemy.exc.OperationalError: msg = ('%s does not match database admin ' 'credentials or database does not exist.') LOG.exception(msg % engine.url) raise exc.DBConnectionError(msg % engine.url) def create_database(engine): """Provide temporary user and database for each particular test.""" driver = engine.name auth = { 'database': ''.join(random.choice(string.ascii_lowercase) for i in moves.range(10)), 'user': engine.url.username, 'passwd': engine.url.password, } sqls = [ "drop database if exists %(database)s;", "create database %(database)s;" ] if driver == 'sqlite': return 'sqlite:////tmp/%s' % auth['database'] elif driver in ['mysql', 'postgresql']: sql_query = map(lambda x: x % auth, sqls) _execute_sql(engine, sql_query, driver) else: raise ValueError('Unsupported RDBMS %s' % driver) params = auth.copy() params['backend'] = driver return "%(backend)s://%(user)s:%(passwd)s@localhost/%(database)s" % params def drop_database(admin_engine, current_uri): """Drop temporary database and user after each particular test.""" engine = get_engine(current_uri) driver = engine.name auth = {'database': engine.url.database, 'user': engine.url.username} if driver == 'sqlite': try: os.remove(auth['database']) except OSError: pass elif driver in ['mysql', 'postgresql']: sql = "drop database if exists %(database)s;" _execute_sql(admin_engine, [sql % auth], driver) else: raise ValueError('Unsupported RDBMS %s' % driver) def main(): """Controller to handle commands ::create: Create test user and database with random names. ::drop: Drop user and database created by previous command. """ parser = argparse.ArgumentParser( description='Controller to handle database creation and dropping' ' commands.', epilog='Under normal circumstances is not used directly.' ' Used in .testr.conf to automate test database creation' ' and dropping processes.') subparsers = parser.add_subparsers( help='Subcommands to manipulate temporary test databases.') create = subparsers.add_parser( 'create', help='Create temporary test ' 'databases and users.') create.set_defaults(which='create') create.add_argument( 'instances_count', type=int, help='Number of databases to create.') drop = subparsers.add_parser( 'drop', help='Drop temporary test databases and users.') drop.set_defaults(which='drop') drop.add_argument( 'instances', nargs='+', help='List of databases uri to be dropped.') args = parser.parse_args() connection_string = os.getenv('OS_TEST_DBAPI_ADMIN_CONNECTION', 'sqlite://') engine = get_engine(connection_string) which = args.which if which == "create": for i in range(int(args.instances_count)): print(create_database(engine)) elif which == "drop": for db in args.instances: drop_database(engine, db) if __name__ == "__main__": main() glance-2014.1/glance/openstack/common/db/sqlalchemy/models.py0000664000175400017540000000755412323736226025305 0ustar jenkinsjenkins00000000000000# Copyright (c) 2011 X.commerce, a business unit of eBay Inc. # Copyright 2010 United States Government as represented by the # Administrator of the National Aeronautics and Space Administration. # Copyright 2011 Piston Cloud Computing, Inc. # Copyright 2012 Cloudscaling Group, 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. """ SQLAlchemy models. """ import six from sqlalchemy import Column, Integer from sqlalchemy import DateTime from sqlalchemy.orm import object_mapper from glance.openstack.common import timeutils class ModelBase(six.Iterator): """Base class for models.""" __table_initialized__ = False def save(self, session): """Save this object.""" # NOTE(boris-42): This part of code should be look like: # session.add(self) # session.flush() # But there is a bug in sqlalchemy and eventlet that # raises NoneType exception if there is no running # transaction and rollback is called. As long as # sqlalchemy has this bug we have to create transaction # explicitly. with session.begin(subtransactions=True): session.add(self) session.flush() def __setitem__(self, key, value): setattr(self, key, value) def __getitem__(self, key): return getattr(self, key) def get(self, key, default=None): return getattr(self, key, default) @property def _extra_keys(self): """Specifies custom fields Subclasses can override this property to return a list of custom fields that should be included in their dict representation. For reference check tests/db/sqlalchemy/test_models.py """ return [] def __iter__(self): columns = dict(object_mapper(self).columns).keys() # NOTE(russellb): Allow models to specify other keys that can be looked # up, beyond the actual db columns. An example would be the 'name' # property for an Instance. columns.extend(self._extra_keys) self._i = iter(columns) return self # In Python 3, __next__() has replaced next(). def __next__(self): n = six.advance_iterator(self._i) return n, getattr(self, n) def next(self): return self.__next__() def update(self, values): """Make the model object behave like a dict.""" for k, v in six.iteritems(values): setattr(self, k, v) def iteritems(self): """Make the model object behave like a dict. Includes attributes from joins. """ local = dict(self) joined = dict([(k, v) for k, v in six.iteritems(self.__dict__) if not k[0] == '_']) local.update(joined) return six.iteritems(local) class TimestampMixin(object): created_at = Column(DateTime, default=lambda: timeutils.utcnow()) updated_at = Column(DateTime, onupdate=lambda: timeutils.utcnow()) class SoftDeleteMixin(object): deleted_at = Column(DateTime) deleted = Column(Integer, default=0) def soft_delete(self, session): """Mark this object as deleted.""" self.deleted = self.id self.deleted_at = timeutils.utcnow() self.save(session=session) glance-2014.1/glance/openstack/common/db/sqlalchemy/test_base.py0000664000175400017540000001153012323736226025760 0ustar jenkinsjenkins00000000000000# Copyright (c) 2013 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import abc import functools import os import fixtures import six from glance.openstack.common.db.sqlalchemy import session from glance.openstack.common.db.sqlalchemy import utils from glance.openstack.common.fixture import lockutils from glance.openstack.common import test class DbFixture(fixtures.Fixture): """Basic database fixture. Allows to run tests on various db backends, such as SQLite, MySQL and PostgreSQL. By default use sqlite backend. To override default backend uri set env variable OS_TEST_DBAPI_CONNECTION with database admin credentials for specific backend. """ def _get_uri(self): return os.getenv('OS_TEST_DBAPI_CONNECTION', 'sqlite://') def __init__(self, test): super(DbFixture, self).__init__() self.test = test def setUp(self): super(DbFixture, self).setUp() self.test.engine = session.create_engine(self._get_uri()) self.test.sessionmaker = session.get_maker(self.test.engine) self.addCleanup(self.test.engine.dispose) class DbTestCase(test.BaseTestCase): """Base class for testing of DB code. Using `DbFixture`. Intended to be the main database test case to use all the tests on a given backend with user defined uri. Backend specific tests should be decorated with `backend_specific` decorator. """ FIXTURE = DbFixture def setUp(self): super(DbTestCase, self).setUp() self.useFixture(self.FIXTURE(self)) ALLOWED_DIALECTS = ['sqlite', 'mysql', 'postgresql'] def backend_specific(*dialects): """Decorator to skip backend specific tests on inappropriate engines. ::dialects: list of dialects names under which the test will be launched. """ def wrap(f): @functools.wraps(f) def ins_wrap(self): if not set(dialects).issubset(ALLOWED_DIALECTS): raise ValueError( "Please use allowed dialects: %s" % ALLOWED_DIALECTS) if self.engine.name not in dialects: msg = ('The test "%s" can be run ' 'only on %s. Current engine is %s.') args = (f.__name__, ' '.join(dialects), self.engine.name) self.skip(msg % args) else: return f(self) return ins_wrap return wrap @six.add_metaclass(abc.ABCMeta) class OpportunisticFixture(DbFixture): """Base fixture to use default CI databases. The databases exist in OpenStack CI infrastructure. But for the correct functioning in local environment the databases must be created manually. """ DRIVER = abc.abstractproperty(lambda: None) DBNAME = PASSWORD = USERNAME = 'openstack_citest' def _get_uri(self): return utils.get_connect_string(backend=self.DRIVER, user=self.USERNAME, passwd=self.PASSWORD, database=self.DBNAME) @six.add_metaclass(abc.ABCMeta) class OpportunisticTestCase(DbTestCase): """Base test case to use default CI databases. The subclasses of the test case are running only when openstack_citest database is available otherwise a tests will be skipped. """ FIXTURE = abc.abstractproperty(lambda: None) def setUp(self): # TODO(bnemec): Remove this once infra is ready for # https://review.openstack.org/#/c/74963/ to merge. self.useFixture(lockutils.LockFixture('opportunistic-db')) credentials = { 'backend': self.FIXTURE.DRIVER, 'user': self.FIXTURE.USERNAME, 'passwd': self.FIXTURE.PASSWORD, 'database': self.FIXTURE.DBNAME} if self.FIXTURE.DRIVER and not utils.is_backend_avail(**credentials): msg = '%s backend is not available.' % self.FIXTURE.DRIVER return self.skip(msg) super(OpportunisticTestCase, self).setUp() class MySQLOpportunisticFixture(OpportunisticFixture): DRIVER = 'mysql' class PostgreSQLOpportunisticFixture(OpportunisticFixture): DRIVER = 'postgresql' class MySQLOpportunisticTestCase(OpportunisticTestCase): FIXTURE = MySQLOpportunisticFixture class PostgreSQLOpportunisticTestCase(OpportunisticTestCase): FIXTURE = PostgreSQLOpportunisticFixture glance-2014.1/glance/openstack/common/db/sqlalchemy/test_migrations.py0000664000175400017540000002550312323736230027222 0ustar jenkinsjenkins00000000000000# Copyright 2010-2011 OpenStack Foundation # Copyright 2012-2013 IBM Corp. # 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 functools import logging import os import subprocess import lockfile from six import moves from six.moves.urllib import parse import sqlalchemy import sqlalchemy.exc from glance.openstack.common.db.sqlalchemy import utils from glance.openstack.common.gettextutils import _LE from glance.openstack.common import test LOG = logging.getLogger(__name__) def _have_mysql(user, passwd, database): present = os.environ.get('TEST_MYSQL_PRESENT') if present is None: return utils.is_backend_avail(backend='mysql', user=user, passwd=passwd, database=database) return present.lower() in ('', 'true') def _have_postgresql(user, passwd, database): present = os.environ.get('TEST_POSTGRESQL_PRESENT') if present is None: return utils.is_backend_avail(backend='postgres', user=user, passwd=passwd, database=database) return present.lower() in ('', 'true') def _set_db_lock(lock_path=None, lock_prefix=None): def decorator(f): @functools.wraps(f) def wrapper(*args, **kwargs): try: path = lock_path or os.environ.get("GLANCE_LOCK_PATH") lock = lockfile.FileLock(os.path.join(path, lock_prefix)) with lock: LOG.debug('Got lock "%s"' % f.__name__) return f(*args, **kwargs) finally: LOG.debug('Lock released "%s"' % f.__name__) return wrapper return decorator class BaseMigrationTestCase(test.BaseTestCase): """Base class fort testing of migration utils.""" def __init__(self, *args, **kwargs): super(BaseMigrationTestCase, self).__init__(*args, **kwargs) self.DEFAULT_CONFIG_FILE = os.path.join(os.path.dirname(__file__), 'test_migrations.conf') # Test machines can set the TEST_MIGRATIONS_CONF variable # to override the location of the config file for migration testing self.CONFIG_FILE_PATH = os.environ.get('TEST_MIGRATIONS_CONF', self.DEFAULT_CONFIG_FILE) self.test_databases = {} self.migration_api = None def setUp(self): super(BaseMigrationTestCase, self).setUp() # Load test databases from the config file. Only do this # once. No need to re-run this on each test... LOG.debug('config_path is %s' % self.CONFIG_FILE_PATH) if os.path.exists(self.CONFIG_FILE_PATH): cp = moves.configparser.RawConfigParser() try: cp.read(self.CONFIG_FILE_PATH) defaults = cp.defaults() for key, value in defaults.items(): self.test_databases[key] = value except moves.configparser.ParsingError as e: self.fail("Failed to read test_migrations.conf config " "file. Got error: %s" % e) else: self.fail("Failed to find test_migrations.conf config " "file.") self.engines = {} for key, value in self.test_databases.items(): self.engines[key] = sqlalchemy.create_engine(value) # We start each test case with a completely blank slate. self._reset_databases() def tearDown(self): # We destroy the test data store between each test case, # and recreate it, which ensures that we have no side-effects # from the tests self._reset_databases() super(BaseMigrationTestCase, self).tearDown() def execute_cmd(self, cmd=None): process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) output = process.communicate()[0] LOG.debug(output) self.assertEqual(0, process.returncode, "Failed to run: %s\n%s" % (cmd, output)) def _reset_pg(self, conn_pieces): (user, password, database, host) = utils.get_db_connection_info(conn_pieces) os.environ['PGPASSWORD'] = password os.environ['PGUSER'] = user # note(boris-42): We must create and drop database, we can't # drop database which we have connected to, so for such # operations there is a special database template1. sqlcmd = ("psql -w -U %(user)s -h %(host)s -c" " '%(sql)s' -d template1") sql = ("drop database if exists %s;") % database droptable = sqlcmd % {'user': user, 'host': host, 'sql': sql} self.execute_cmd(droptable) sql = ("create database %s;") % database createtable = sqlcmd % {'user': user, 'host': host, 'sql': sql} self.execute_cmd(createtable) os.unsetenv('PGPASSWORD') os.unsetenv('PGUSER') @_set_db_lock(lock_prefix='migration_tests-') def _reset_databases(self): for key, engine in self.engines.items(): conn_string = self.test_databases[key] conn_pieces = parse.urlparse(conn_string) engine.dispose() if conn_string.startswith('sqlite'): # We can just delete the SQLite database, which is # the easiest and cleanest solution db_path = conn_pieces.path.strip('/') if os.path.exists(db_path): os.unlink(db_path) # No need to recreate the SQLite DB. SQLite will # create it for us if it's not there... elif conn_string.startswith('mysql'): # We can execute the MySQL client to destroy and re-create # the MYSQL database, which is easier and less error-prone # than using SQLAlchemy to do this via MetaData...trust me. (user, password, database, host) = \ utils.get_db_connection_info(conn_pieces) sql = ("drop database if exists %(db)s; " "create database %(db)s;") % {'db': database} cmd = ("mysql -u \"%(user)s\" -p\"%(password)s\" -h %(host)s " "-e \"%(sql)s\"") % {'user': user, 'password': password, 'host': host, 'sql': sql} self.execute_cmd(cmd) elif conn_string.startswith('postgresql'): self._reset_pg(conn_pieces) class WalkVersionsMixin(object): def _walk_versions(self, engine=None, snake_walk=False, downgrade=True): # Determine latest version script from the repo, then # upgrade from 1 through to the latest, with no data # in the databases. This just checks that the schema itself # upgrades successfully. # Place the database under version control self.migration_api.version_control(engine, self.REPOSITORY, self.INIT_VERSION) self.assertEqual(self.INIT_VERSION, self.migration_api.db_version(engine, self.REPOSITORY)) LOG.debug('latest version is %s' % self.REPOSITORY.latest) versions = range(self.INIT_VERSION + 1, self.REPOSITORY.latest + 1) for version in versions: # upgrade -> downgrade -> upgrade self._migrate_up(engine, version, with_data=True) if snake_walk: downgraded = self._migrate_down( engine, version - 1, with_data=True) if downgraded: self._migrate_up(engine, version) if downgrade: # Now walk it back down to 0 from the latest, testing # the downgrade paths. for version in reversed(versions): # downgrade -> upgrade -> downgrade downgraded = self._migrate_down(engine, version - 1) if snake_walk and downgraded: self._migrate_up(engine, version) self._migrate_down(engine, version - 1) def _migrate_down(self, engine, version, with_data=False): try: self.migration_api.downgrade(engine, self.REPOSITORY, version) except NotImplementedError: # NOTE(sirp): some migrations, namely release-level # migrations, don't support a downgrade. return False self.assertEqual( version, self.migration_api.db_version(engine, self.REPOSITORY)) # NOTE(sirp): `version` is what we're downgrading to (i.e. the 'target' # version). So if we have any downgrade checks, they need to be run for # the previous (higher numbered) migration. if with_data: post_downgrade = getattr( self, "_post_downgrade_%03d" % (version + 1), None) if post_downgrade: post_downgrade(engine) return True def _migrate_up(self, engine, version, with_data=False): """migrate up to a new version of the db. We allow for data insertion and post checks at every migration version with special _pre_upgrade_### and _check_### functions in the main test. """ # NOTE(sdague): try block is here because it's impossible to debug # where a failed data migration happens otherwise try: if with_data: data = None pre_upgrade = getattr( self, "_pre_upgrade_%03d" % version, None) if pre_upgrade: data = pre_upgrade(engine) self.migration_api.upgrade(engine, self.REPOSITORY, version) self.assertEqual(version, self.migration_api.db_version(engine, self.REPOSITORY)) if with_data: check = getattr(self, "_check_%03d" % version, None) if check: check(engine, data) except Exception: LOG.error(_LE("Failed to migrate to version %s on engine %s") % (version, engine)) raise glance-2014.1/glance/openstack/common/db/sqlalchemy/__init__.py0000664000175400017540000000000012323736226025534 0ustar jenkinsjenkins00000000000000glance-2014.1/glance/openstack/common/db/exception.py0000664000175400017540000000352012323736226023643 0ustar jenkinsjenkins00000000000000# Copyright 2010 United States Government as represented by the # Administrator of the National Aeronautics and Space Administration. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """DB related custom exceptions.""" import six from glance.openstack.common.gettextutils import _ class DBError(Exception): """Wraps an implementation specific exception.""" def __init__(self, inner_exception=None): self.inner_exception = inner_exception super(DBError, self).__init__(six.text_type(inner_exception)) class DBDuplicateEntry(DBError): """Wraps an implementation specific exception.""" def __init__(self, columns=[], inner_exception=None): self.columns = columns super(DBDuplicateEntry, self).__init__(inner_exception) class DBDeadlock(DBError): def __init__(self, inner_exception=None): super(DBDeadlock, self).__init__(inner_exception) class DBInvalidUnicodeParameter(Exception): message = _("Invalid Parameter: " "Unicode is not supported by the current database.") class DbMigrationError(DBError): """Wraps migration specific exception.""" def __init__(self, message=None): super(DbMigrationError, self).__init__(message) class DBConnectionError(DBError): """Wraps connection specific exception.""" pass glance-2014.1/glance/openstack/common/db/api.py0000664000175400017540000001354212323736226022423 0ustar jenkinsjenkins00000000000000# Copyright (c) 2013 Rackspace Hosting # 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. """Multiple DB API backend support. A DB backend module should implement a method named 'get_backend' which takes no arguments. The method can return any object that implements DB API methods. """ import functools import logging import threading import time from glance.openstack.common.db import exception from glance.openstack.common.gettextutils import _LE from glance.openstack.common import importutils LOG = logging.getLogger(__name__) def safe_for_db_retry(f): """Enable db-retry for decorated function, if config option enabled.""" f.__dict__['enable_retry'] = True return f class wrap_db_retry(object): """Retry db.api methods, if DBConnectionError() raised Retry decorated db.api methods. If we enabled `use_db_reconnect` in config, this decorator will be applied to all db.api functions, marked with @safe_for_db_retry decorator. Decorator catchs DBConnectionError() and retries function in a loop until it succeeds, or until maximum retries count will be reached. """ def __init__(self, retry_interval, max_retries, inc_retry_interval, max_retry_interval): super(wrap_db_retry, self).__init__() self.retry_interval = retry_interval self.max_retries = max_retries self.inc_retry_interval = inc_retry_interval self.max_retry_interval = max_retry_interval def __call__(self, f): @functools.wraps(f) def wrapper(*args, **kwargs): next_interval = self.retry_interval remaining = self.max_retries while True: try: return f(*args, **kwargs) except exception.DBConnectionError as e: if remaining == 0: LOG.exception(_LE('DB exceeded retry limit.')) raise exception.DBError(e) if remaining != -1: remaining -= 1 LOG.exception(_LE('DB connection error.')) # NOTE(vsergeyev): We are using patched time module, so # this effectively yields the execution # context to another green thread. time.sleep(next_interval) if self.inc_retry_interval: next_interval = min( next_interval * 2, self.max_retry_interval ) return wrapper class DBAPI(object): def __init__(self, backend_name, backend_mapping=None, lazy=False, **kwargs): """Initialize the chosen DB API backend. :param backend_name: name of the backend to load :type backend_name: str :param backend_mapping: backend name -> module/class to load mapping :type backend_mapping: dict :param lazy: load the DB backend lazily on the first DB API method call :type lazy: bool Keyword arguments: :keyword use_db_reconnect: retry DB transactions on disconnect or not :type use_db_reconnect: bool :keyword retry_interval: seconds between transaction retries :type retry_interval: int :keyword inc_retry_interval: increase retry interval or not :type inc_retry_interval: bool :keyword max_retry_interval: max interval value between retries :type max_retry_interval: int :keyword max_retries: max number of retries before an error is raised :type max_retries: int """ self._backend = None self._backend_name = backend_name self._backend_mapping = backend_mapping or {} self._lock = threading.Lock() if not lazy: self._load_backend() self.use_db_reconnect = kwargs.get('use_db_reconnect', False) self.retry_interval = kwargs.get('retry_interval', 1) self.inc_retry_interval = kwargs.get('inc_retry_interval', True) self.max_retry_interval = kwargs.get('max_retry_interval', 10) self.max_retries = kwargs.get('max_retries', 20) def _load_backend(self): with self._lock: if not self._backend: # Import the untranslated name if we don't have a mapping backend_path = self._backend_mapping.get(self._backend_name, self._backend_name) backend_mod = importutils.import_module(backend_path) self._backend = backend_mod.get_backend() def __getattr__(self, key): if not self._backend: self._load_backend() attr = getattr(self._backend, key) if not hasattr(attr, '__call__'): return attr # NOTE(vsergeyev): If `use_db_reconnect` option is set to True, retry # DB API methods, decorated with @safe_for_db_retry # on disconnect. if self.use_db_reconnect and hasattr(attr, 'enable_retry'): attr = wrap_db_retry( retry_interval=self.retry_interval, max_retries=self.max_retries, inc_retry_interval=self.inc_retry_interval, max_retry_interval=self.max_retry_interval)(attr) return attr glance-2014.1/glance/openstack/common/db/__init__.py0000664000175400017540000000000012323736226023372 0ustar jenkinsjenkins00000000000000glance-2014.1/glance/openstack/common/__init__.py0000664000175400017540000000120412323736226023014 0ustar jenkinsjenkins00000000000000# # 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 six six.add_move(six.MovedModule('mox', 'mox', 'mox3.mox')) glance-2014.1/glance/openstack/__init__.py0000664000175400017540000000000012323736226021515 0ustar jenkinsjenkins00000000000000glance-2014.1/glance/cmd/0000775000175400017540000000000012323736427016175 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/cmd/manage.py0000775000175400017540000002406212323736226020003 0ustar jenkinsjenkins00000000000000#!/usr/bin/env python # Copyright 2010 United States Government as represented by the # Administrator of the National Aeronautics and Space Administration. # Copyright 2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ Glance Management Utility """ from __future__ import print_function # FIXME(sirp): When we have glance-admin we can consider merging this into it # Perhaps for consistency with Nova, we would then rename glance-admin -> # glance-manage (or the other way around) 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) from oslo.config import cfg from glance.common import config from glance.common import exception from glance.db import migration as db_migration from glance.db.sqlalchemy import api as db_api from glance.openstack.common.db.sqlalchemy import migration from glance.openstack.common import log from glance.openstack.common import strutils LOG = log.getLogger(__name__) manager_opts = [ cfg.BoolOpt('db_enforce_mysql_charset', default=True, help=_('DEPRECATED. TO BE REMOVED IN THE JUNO RELEASE. ' 'Whether or not to enforce that all DB tables have ' 'charset utf8. If your database tables do not have ' 'charset utf8 you will need to convert before this ' 'option is removed. This option is only relevant if ' 'your database engine is MySQL.')) ] CONF = cfg.CONF CONF.register_opts(manager_opts) CONF.import_group("database", "glance.openstack.common.db.options") # Decorators for actions def args(*args, **kwargs): def _decorator(func): func.__dict__.setdefault('args', []).insert(0, (args, kwargs)) return func return _decorator class DbCommands(object): """Class for managing the db""" def __init__(self): pass def _need_sanity_check(self): if not CONF.db_enforce_mysql_charset: LOG.warning(_('Warning: ' 'The db_enforce_mysql_charset option is now ' 'deprecated and will be removed in the Juno ' 'release. Please migrate DB manually e.g. ' 'convert data of all tables to UTF-8 charset.')) return CONF.db_enforce_mysql_charset def version(self): """Print database's current migration level""" print(migration.db_version(db_api.get_engine(), db_migration.MIGRATE_REPO_PATH, db_migration.INIT_VERSION)) @args('--version', metavar='', help='Database version') def upgrade(self, version=None): """Upgrade the database's migration level""" migration.db_sync(db_api.get_engine(), db_migration.MIGRATE_REPO_PATH, version, sanity_check=self._need_sanity_check()) @args('--version', metavar='', help='Database version') def downgrade(self, version=None): """Downgrade the database's migration level""" migration.db_sync(db_api.get_engine(), db_migration.MIGRATE_REPO_PATH, version, sanity_check=self._need_sanity_check()) @args('--version', metavar='', help='Database version') def version_control(self, version=None): """Place a database under migration control""" migration.db_version_control(db_api.get_engine(), db_migration.MIGRATE_REPO_PATH, version) @args('--version', metavar='', help='Database version') @args('--current_version', metavar='', help='Current Database version') def sync(self, version=None, current_version=None): """ Place a database under migration control and upgrade/downgrade it, creating first if necessary. """ if current_version not in (None, 'None'): migration.db_version_control(db_api.get_engine(), db_migration.MIGRATE_REPO_PATH, version=current_version) migration.db_sync(db_api.get_engine(), db_migration.MIGRATE_REPO_PATH, version, sanity_check=self._need_sanity_check()) class DbLegacyCommands(object): """Class for managing the db using legacy commands""" def __init__(self, command_object): self.command_object = command_object def version(self): self.command_object.version() def upgrade(self, version=None): self.command_object.upgrade(CONF.command.version) def downgrade(self, version=None): self.command_object.downgrade(CONF.command.version) def version_control(self, version=None): self.command_object.version_control(CONF.command.version) def sync(self, version=None, current_version=None): self.command_object.sync(CONF.command.version, CONF.command.current_version) def add_legacy_command_parsers(command_object, subparsers): legacy_command_object = DbLegacyCommands(command_object) parser = subparsers.add_parser('db_version') parser.set_defaults(action_fn=legacy_command_object.version) parser.set_defaults(action='db_version') parser = subparsers.add_parser('db_upgrade') parser.set_defaults(action_fn=legacy_command_object.upgrade) parser.add_argument('version', nargs='?') parser.set_defaults(action='db_upgrade') parser = subparsers.add_parser('db_downgrade') parser.set_defaults(action_fn=legacy_command_object.downgrade) parser.add_argument('version') parser.set_defaults(action='db_downgrade') parser = subparsers.add_parser('db_version_control') parser.set_defaults(action_fn=legacy_command_object.version_control) parser.add_argument('version', nargs='?') parser.set_defaults(action='db_version_control') parser = subparsers.add_parser('db_sync') parser.set_defaults(action_fn=legacy_command_object.sync) parser.add_argument('version', nargs='?') parser.add_argument('current_version', nargs='?') parser.set_defaults(action='db_sync') def add_command_parsers(subparsers): command_object = DbCommands() parser = subparsers.add_parser('db') parser.set_defaults(command_object=command_object) category_subparsers = parser.add_subparsers(dest='action') for (action, action_fn) in methods_of(command_object): parser = category_subparsers.add_parser(action) action_kwargs = [] for args, kwargs in getattr(action_fn, 'args', []): # FIXME(basha): hack to assume dest is the arg name without # the leading hyphens if no dest is supplied kwargs.setdefault('dest', args[0][2:]) if kwargs['dest'].startswith('action_kwarg_'): action_kwargs.append( kwargs['dest'][len('action_kwarg_'):]) else: action_kwargs.append(kwargs['dest']) kwargs['dest'] = 'action_kwarg_' + kwargs['dest'] parser.add_argument(*args, **kwargs) parser.set_defaults(action_fn=action_fn) parser.set_defaults(action_kwargs=action_kwargs) parser.add_argument('action_args', nargs='*') add_legacy_command_parsers(command_object, subparsers) command_opt = cfg.SubCommandOpt('command', title='Commands', help='Available commands', handler=add_command_parsers) def methods_of(obj): """Get all callable methods of an object that don't start with underscore returns a list of tuples of the form (method_name, method) """ result = [] for i in dir(obj): if callable(getattr(obj, i)) and not i.startswith('_'): result.append((i, getattr(obj, i))) return result def main(): CONF.register_cli_opt(command_opt) try: cfg_files = cfg.find_config_files(project='glance', prog='glance-registry') cfg_files.extend(cfg.find_config_files(project='glance', prog='glance-api')) config.parse_args(default_config_files=cfg_files, usage="%(prog)s [options] ") log.setup('glance') except RuntimeError as e: sys.exit("ERROR: %s" % e) try: if CONF.command.action.startswith('db'): return CONF.command.action_fn() else: func_kwargs = {} for k in CONF.command.action_kwargs: v = getattr(CONF.command, 'action_kwarg_' + k) if v is None: continue func_kwargs[k] = strutils.safe_decode(v) func_args = [strutils.safe_decode(arg) for arg in CONF.command.action_args] return CONF.command.action_fn(*func_args, **func_kwargs) except exception.GlanceException as e: sys.exit("ERROR: %s" % e) if __name__ == '__main__': main() glance-2014.1/glance/cmd/cache_manage.py0000775000175400017540000004022312323736226021123 0ustar jenkinsjenkins00000000000000#!/usr/bin/env python # Copyright 2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ A simple cache management utility for Glance. """ from __future__ import print_function import functools import optparse import os import sys import time # 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) from glance.common import exception from glance.common import utils import glance.image_cache.client from glance.openstack.common import timeutils from glance.version import version_info as version SUCCESS = 0 FAILURE = 1 def catch_error(action): """Decorator to provide sensible default error handling for actions.""" def wrap(func): @functools.wraps(func) def wrapper(*args, **kwargs): try: ret = func(*args, **kwargs) return SUCCESS if ret is None else ret except exception.NotFound: options = args[0] print("Cache management middleware not enabled on host %s" % options.host) return FAILURE except exception.Forbidden: print("Not authorized to make this request.") return FAILURE except Exception as e: options = args[0] if options.debug: raise print("Failed to %s. Got error:" % action) pieces = unicode(e).split('\n') for piece in pieces: print(piece) return FAILURE return wrapper return wrap @catch_error('show cached images') def list_cached(options, args): """%(prog)s list-cached [options] List all images currently cached. """ client = get_client(options) images = client.get_cached_images() if not images: print("No cached images.") return SUCCESS print("Found %d cached images..." % len(images)) pretty_table = utils.PrettyTable() pretty_table.add_column(36, label="ID") pretty_table.add_column(19, label="Last Accessed (UTC)") pretty_table.add_column(19, label="Last Modified (UTC)") # 1 TB takes 13 characters to display: len(str(2**40)) == 13 pretty_table.add_column(14, label="Size", just="r") pretty_table.add_column(10, label="Hits", just="r") print(pretty_table.make_header()) for image in images: last_modified = image['last_modified'] last_modified = timeutils.iso8601_from_timestamp(last_modified) last_accessed = image['last_accessed'] if last_accessed == 0: last_accessed = "N/A" else: last_accessed = timeutils.iso8601_from_timestamp(last_accessed) print(pretty_table.make_row( image['image_id'], last_accessed, last_modified, image['size'], image['hits'])) @catch_error('show queued images') def list_queued(options, args): """%(prog)s list-queued [options] List all images currently queued for caching. """ client = get_client(options) images = client.get_queued_images() if not images: print("No queued images.") return SUCCESS print("Found %d queued images..." % len(images)) pretty_table = utils.PrettyTable() pretty_table.add_column(36, label="ID") print(pretty_table.make_header()) for image in images: print(pretty_table.make_row(image)) @catch_error('queue the specified image for caching') def queue_image(options, args): """%(prog)s queue-image [options] Queues an image for caching """ if len(args) == 1: image_id = args.pop() else: print("Please specify one and only ID of the image you wish to ") print("queue from the cache as the first argument") return FAILURE if (not options.force and not user_confirm("Queue image %(image_id)s for caching?" % {'image_id': image_id}, default=False)): return SUCCESS client = get_client(options) client.queue_image_for_caching(image_id) if options.verbose: print("Queued image %(image_id)s for caching" % {'image_id': image_id}) return SUCCESS @catch_error('delete the specified cached image') def delete_cached_image(options, args): """ %(prog)s delete-cached-image [options] Deletes an image from the cache """ if len(args) == 1: image_id = args.pop() else: print("Please specify one and only ID of the image you wish to ") print("delete from the cache as the first argument") return FAILURE if (not options.force and not user_confirm("Delete cached image %(image_id)s?" % {'image_id': image_id}, default=False)): return SUCCESS client = get_client(options) client.delete_cached_image(image_id) if options.verbose: print("Deleted cached image %(image_id)s" % {'image_id': image_id}) return SUCCESS @catch_error('Delete all cached images') def delete_all_cached_images(options, args): """%(prog)s delete-all-cached-images [options] Remove all images from the cache. """ if (not options.force and not user_confirm("Delete all cached images?", default=False)): return SUCCESS client = get_client(options) num_deleted = client.delete_all_cached_images() if options.verbose: print("Deleted %(num_deleted)s cached images" % {'num_deleted': num_deleted}) return SUCCESS @catch_error('delete the specified queued image') def delete_queued_image(options, args): """ %(prog)s delete-queued-image [options] Deletes an image from the cache """ if len(args) == 1: image_id = args.pop() else: print("Please specify one and only ID of the image you wish to ") print("delete from the cache as the first argument") return FAILURE if (not options.force and not user_confirm("Delete queued image %(image_id)s?" % {'image_id': image_id}, default=False)): return SUCCESS client = get_client(options) client.delete_queued_image(image_id) if options.verbose: print("Deleted queued image %(image_id)s" % {'image_id': image_id}) return SUCCESS @catch_error('Delete all queued images') def delete_all_queued_images(options, args): """%(prog)s delete-all-queued-images [options] Remove all images from the cache queue. """ if (not options.force and not user_confirm("Delete all queued images?", default=False)): return SUCCESS client = get_client(options) num_deleted = client.delete_all_queued_images() if options.verbose: print("Deleted %(num_deleted)s queued images" % {'num_deleted': num_deleted}) return SUCCESS def get_client(options): """Return a new client object to a Glance server. specified by the --host and --port options supplied to the CLI """ return glance.image_cache.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 env(*vars, **kwargs): """Search for the first defined of possibly many env vars. Returns the first environment variable defined in vars, or returns the default defined in kwargs. """ for v in vars: value = os.environ.get(v, None) if value: return value return kwargs.get('default', '') def create_options(parser): """Set up the CLI and config-file options that may be parsed and program commands. :param parser: The option parser """ parser.add_option('-v', '--verbose', default=False, action="store_true", help="Print more verbose output.") parser.add_option('-d', '--debug', default=False, action="store_true", help="Print debugging output.") parser.add_option('-H', '--host', metavar="ADDRESS", default="0.0.0.0", help="Address of Glance API host. " "Default: %default.") parser.add_option('-p', '--port', dest="port", metavar="PORT", type=int, default=9292, help="Port the Glance API host listens on. " "Default: %default.") 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('-f', '--force', dest="force", metavar="FORCE", default=False, action="store_true", help="Prevent select actions from requesting " "user confirmation.") parser.add_option('--os-auth-token', dest='os_auth_token', default=env('OS_AUTH_TOKEN'), help='Defaults to env[OS_AUTH_TOKEN].') parser.add_option('-A', '--os_auth_token', '--auth_token', dest='os_auth_token', help=optparse.SUPPRESS_HELP) parser.add_option('--os-username', dest='os_username', default=env('OS_USERNAME'), help='Defaults to env[OS_USERNAME].') parser.add_option('-I', '--os_username', dest='os_username', help=optparse.SUPPRESS_HELP) parser.add_option('--os-password', dest='os_password', default=env('OS_PASSWORD'), help='Defaults to env[OS_PASSWORD].') parser.add_option('-K', '--os_password', dest='os_password', help=optparse.SUPPRESS_HELP) parser.add_option('--os-region-name', dest='os_region_name', default=env('OS_REGION_NAME'), help='Defaults to env[OS_REGION_NAME].') parser.add_option('-R', '--os_region_name', dest='os_region_name', help=optparse.SUPPRESS_HELP) parser.add_option('--os-tenant-id', dest='os_tenant_id', default=env('OS_TENANT_ID'), help='Defaults to env[OS_TENANT_ID].') parser.add_option('--os_tenant_id', dest='os_tenant_id', help=optparse.SUPPRESS_HELP) parser.add_option('--os-tenant-name', dest='os_tenant_name', default=env('OS_TENANT_NAME'), help='Defaults to env[OS_TENANT_NAME].') parser.add_option('-T', '--os_tenant_name', dest='os_tenant_name', help=optparse.SUPPRESS_HELP) parser.add_option('--os-auth-url', default=env('OS_AUTH_URL'), help='Defaults to env[OS_AUTH_URL].') parser.add_option('-N', '--os_auth_url', dest='os_auth_url', help=optparse.SUPPRESS_HELP) parser.add_option('-S', '--os_auth_strategy', dest="os_auth_strategy", metavar="STRATEGY", default=None, help="Authentication strategy (keystone or noauth).") def parse_options(parser, cli_args): """ Returns the parsed CLI options, command to run and its arguments, merged with any same-named options found in a configuration file :param parser: The option parser """ if not cli_args: cli_args.append('-h') # Show options in usage output... (options, args) = parser.parse_args(cli_args) # HACK(sirp): Make the parser available to the print_help method # print_help is a command, so it only accepts (options, args); we could # one-off have it take (parser, options, args), however, for now, I think # this little hack will suffice options.__parser = parser if not args: parser.print_usage() sys.exit(0) command_name = args.pop(0) command = lookup_command(parser, command_name) return (options, command, args) def print_help(options, args): """ Print help specific to a command """ if len(args) != 1: sys.exit("Please specify a command") parser = options.__parser command_name = args.pop() command = lookup_command(parser, command_name) print(command.__doc__ % {'prog': os.path.basename(sys.argv[0])}) def lookup_command(parser, command_name): BASE_COMMANDS = {'help': print_help} CACHE_COMMANDS = { 'list-cached': list_cached, 'list-queued': list_queued, 'queue-image': queue_image, 'delete-cached-image': delete_cached_image, 'delete-all-cached-images': delete_all_cached_images, 'delete-queued-image': delete_queued_image, 'delete-all-queued-images': delete_all_queued_images, } commands = {} for command_set in (BASE_COMMANDS, CACHE_COMMANDS): commands.update(command_set) try: command = commands[command_name] except KeyError: parser.print_usage() sys.exit("Unknown command: %(cmd_name)s" % {'cmd_name': command_name}) return command def user_confirm(prompt, default=False): """Yes/No question dialog with user. :param prompt: question/statement to present to user (string) :param default: boolean value to return if empty string is received as response to prompt """ if default: prompt_default = "[Y/n]" else: prompt_default = "[y/N]" answer = raw_input("%s %s " % (prompt, prompt_default)) if answer == "": return default else: return answer.lower() in ("yes", "y") def main(): usage = """ %prog [options] [args] Commands: help Output help for one of the commands below list-cached List all images currently cached list-queued List all images currently queued for caching queue-image Queue an image for caching delete-cached-image Purges an image from the cache delete-all-cached-images Removes all images from the cache delete-queued-image Deletes an image from the cache queue delete-all-queued-images Deletes all images from the cache queue """ version_string = version.cached_version_string() oparser = optparse.OptionParser(version=version_string, usage=usage.strip()) create_options(oparser) (options, command, args) = parse_options(oparser, sys.argv[1:]) try: start_time = time.time() result = command(options, args) end_time = time.time() if options.verbose: print("Completed in %-0.4f sec." % (end_time - start_time)) sys.exit(result) except (RuntimeError, NotImplementedError) as e: print("ERROR: ", e) if __name__ == '__main__': main() glance-2014.1/glance/cmd/replicator.py0000775000175400017540000006744612323736226020734 0ustar jenkinsjenkins00000000000000#!/usr/bin/env python # Copyright 2012 Michael Still and Canonical 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. from __future__ import print_function import httplib import logging import logging.config import logging.handlers import optparse import os import re import sys import uuid import six.moves.urllib.parse as urlparse from glance.openstack.common import jsonutils # 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) COMMANDS = """Commands: help Output help for one of the commands below compare What is missing from the slave glance? dump Dump the contents of a glance instance to local disk. livecopy Load the contents of one glance instance into another. load Load the contents of a local directory into glance. size Determine the size of a glance instance if dumped to disk. """ IMAGE_ALREADY_PRESENT_MESSAGE = _('The image %s is already present on ' 'the slave, but our check for it did ' 'not find it. This indicates that we ' 'do not have permissions to see all ' 'the images on the slave server.') SERVER_PORT_REGEX = '\w+:\w+' class AuthenticationException(Exception): pass class ImageAlreadyPresentException(Exception): pass class ServerErrorException(Exception): pass class UploadException(Exception): pass class ImageService(object): def __init__(self, conn, auth_token): """Initialize the ImageService. conn: a httplib.HTTPConnection to the glance server auth_token: authentication token to pass in the x-auth-token header """ self.auth_token = auth_token self.conn = conn def _http_request(self, method, url, headers, body, ignore_result_body=False): """Perform an HTTP request against the server. method: the HTTP method to use url: the URL to request (not including server portion) headers: headers for the request body: body to send with the request ignore_result_body: the body of the result will be ignored Returns: a httplib response object """ if self.auth_token: headers.setdefault('x-auth-token', self.auth_token) logging.debug(_('Request: %(method)s http://%(server)s:%(port)s' '%(url)s with headers %(headers)s') % {'method': method, 'server': self.conn.host, 'port': self.conn.port, 'url': url, 'headers': repr(headers)}) self.conn.request(method, url, body, headers) response = self.conn.getresponse() headers = self._header_list_to_dict(response.getheaders()) code = response.status code_description = httplib.responses[code] logging.debug(_('Response: %(code)s %(status)s %(headers)s') % {'code': code, 'status': code_description, 'headers': repr(headers)}) if code in [400, 500]: raise ServerErrorException(response.read()) if code in [401, 403]: raise AuthenticationException(response.read()) if code == 409: raise ImageAlreadyPresentException(response.read()) if ignore_result_body: # NOTE: because we are pipelining requests through a single HTTP # connection, httplib requires that we read the response body # before we can make another request. If the caller knows they # don't care about the body, they can ask us to do that for them. response.read() return response def get_images(self): """Return a detailed list of images. Yields a series of images as dicts containing metadata. """ params = {'is_public': None} while True: url = '/v1/images/detail' query = urlparse.urlencode(params) if query: url += '?%s' % query response = self._http_request('GET', url, {}, '') result = jsonutils.loads(response.read()) if not result or not 'images' in result or not result['images']: return for image in result.get('images', []): params['marker'] = image['id'] yield image def get_image(self, image_uuid): """Fetch image data from glance. image_uuid: the id of an image Returns: a httplib Response object where the body is the image. """ url = '/v1/images/%s' % image_uuid return self._http_request('GET', url, {}, '') @staticmethod def _header_list_to_dict(headers): """Expand a list of headers into a dictionary. headers: a list of [(key, value), (key, value), (key, value)] Returns: a dictionary representation of the list """ d = {} for (header, value) in headers: if header.startswith('x-image-meta-property-'): prop = header.replace('x-image-meta-property-', '') d.setdefault('properties', {}) d['properties'][prop] = value else: d[header.replace('x-image-meta-', '')] = value return d def get_image_meta(self, image_uuid): """Return the metadata for a single image. image_uuid: the id of an image Returns: image metadata as a dictionary """ url = '/v1/images/%s' % image_uuid response = self._http_request('HEAD', url, {}, '', ignore_result_body=True) return self._header_list_to_dict(response.getheaders()) @staticmethod def _dict_to_headers(d): """Convert a dictionary into one suitable for a HTTP request. d: a dictionary Returns: the same dictionary, with x-image-meta added to every key """ h = {} for key in d: if key == 'properties': for subkey in d[key]: if d[key][subkey] is None: h['x-image-meta-property-%s' % subkey] = '' else: h['x-image-meta-property-%s' % subkey] = d[key][subkey] else: h['x-image-meta-%s' % key] = d[key] return h def add_image(self, image_meta, image_data): """Upload an image. image_meta: image metadata as a dictionary image_data: image data as a object with a read() method Returns: a tuple of (http response headers, http response body) """ url = '/v1/images' headers = self._dict_to_headers(image_meta) headers['Content-Type'] = 'application/octet-stream' headers['Content-Length'] = int(image_meta['size']) response = self._http_request('POST', url, headers, image_data) headers = self._header_list_to_dict(response.getheaders()) logging.debug(_('Image post done')) body = response.read() return headers, body def add_image_meta(self, image_meta): """Update image metadata. image_meta: image metadata as a dictionary Returns: a tuple of (http response headers, http response body) """ url = '/v1/images/%s' % image_meta['id'] headers = self._dict_to_headers(image_meta) headers['Content-Type'] = 'application/octet-stream' response = self._http_request('PUT', url, headers, '') headers = self._header_list_to_dict(response.getheaders()) logging.debug(_('Image post done')) body = response.read() return headers, body def get_image_service(): """Get a copy of the image service. This is done like this to make it easier to mock out ImageService. """ return ImageService def replication_size(options, args): """%(prog)s size Determine the size of a glance instance if dumped to disk. server:port: the location of the glance instance. """ # Make sure server info is provided if len(args) < 1: raise TypeError(_("Too few arguments.")) server_port = args.pop() if not re.match(SERVER_PORT_REGEX, server_port): raise ValueError(_("Bad format of the given arguments.")) server, port = server_port.split(':') total_size = 0 count = 0 imageservice = get_image_service() client = imageservice(httplib.HTTPConnection(server, port), options.slavetoken) for image in client.get_images(): logging.debug(_('Considering image: %(image)s') % {'image': image}) if image['status'] == 'active': total_size += int(image['size']) count += 1 print(_('Total size is %(size)d bytes across %(img_count)d images') % {'size': total_size, 'img_count': count}) def replication_dump(options, args): """%(prog)s dump Dump the contents of a glance instance to local disk. server:port: the location of the glance instance. path: a directory on disk to contain the data. """ # Make sure server and path are provided if len(args) < 2: raise TypeError(_("Too few arguments.")) path = args.pop() server_port = args.pop() if not re.match(SERVER_PORT_REGEX, server_port): raise ValueError(_("Bad format of the given arguments.")) server, port = server_port.split(':') imageservice = get_image_service() client = imageservice(httplib.HTTPConnection(server, port), options.mastertoken) for image in client.get_images(): logging.info(_('Considering: %s') % image['id']) data_path = os.path.join(path, image['id']) if not os.path.exists(data_path): logging.info(_('... storing')) # Dump glance information with open(data_path, 'w') as f: f.write(jsonutils.dumps(image)) if image['status'] == 'active' and not options.metaonly: # Now fetch the image. The metadata returned in headers here # is the same as that which we got from the detailed images # request earlier, so we can ignore it here. Note that we also # only dump active images. logging.info(_('... image is active')) image_response = client.get_image(image['id']) with open(data_path + '.img', 'wb') as f: while True: chunk = image_response.read(options.chunksize) if not chunk: break f.write(chunk) def _dict_diff(a, b): """A one way dictionary diff. a: a dictionary b: a dictionary Returns: True if the dictionaries are different """ # Only things the master has which the slave lacks matter if set(a.keys()) - set(b.keys()): logging.debug(_('metadata diff -- master has extra keys: %(keys)s') % {'keys': ' '.join(set(a.keys()) - set(b.keys()))}) return True for key in a: if str(a[key]) != str(b[key]): logging.debug(_('metadata diff -- value differs for key ' '%(key)s: master "%(master_value)s" vs ' 'slave "%(slave_value)s"') % {'key': key, 'master_value': a[key], 'slave_value': b[key]}) return True return False # This is lifted from openstack-common, but copied here to reduce dependancies def is_uuid_like(value): try: uuid.UUID(value) return True except Exception: return False def replication_load(options, args): """%(prog)s load Load the contents of a local directory into glance. server:port: the location of the glance instance. path: a directory on disk containing the data. """ # Make sure server and path are provided if len(args) < 2: raise TypeError(_("Too few arguments.")) path = args.pop() server_port = args.pop() if not re.match(SERVER_PORT_REGEX, server_port): raise ValueError(_("Bad format of the given arguments.")) server, port = server_port.split(':') imageservice = get_image_service() client = imageservice(httplib.HTTPConnection(server, port), options.slavetoken) updated = [] for ent in os.listdir(path): if is_uuid_like(ent): image_uuid = ent logging.info(_('Considering: %s') % image_uuid) meta_file_name = os.path.join(path, image_uuid) with open(meta_file_name) as meta_file: meta = jsonutils.loads(meta_file.read()) # Remove keys which don't make sense for replication for key in options.dontreplicate.split(' '): if key in meta: logging.debug(_('Stripping %(header)s from saved ' 'metadata'), {'header': key}) del meta[key] if _image_present(client, image_uuid): # NOTE(mikal): Perhaps we just need to update the metadata? # Note that we don't attempt to change an image file once it # has been uploaded. logging.debug(_('Image %s already present'), image_uuid) headers = client.get_image_meta(image_uuid) for key in options.dontreplicate.split(' '): if key in headers: logging.debug(_('Stripping %(header)s from slave ' 'metadata'), {'header': key}) del headers[key] if _dict_diff(meta, headers): logging.info(_('... metadata has changed')) headers, body = client.add_image_meta(meta) _check_upload_response_headers(headers, body) updated.append(meta['id']) else: if not os.path.exists(os.path.join(path, image_uuid + '.img')): logging.info(_('... dump is missing image data, skipping')) continue # Upload the image itself with open(os.path.join(path, image_uuid + '.img')) as img_file: try: headers, body = client.add_image(meta, img_file) _check_upload_response_headers(headers, body) updated.append(meta['id']) except ImageAlreadyPresentException: logging.error(IMAGE_ALREADY_PRESENT_MESSAGE % image_uuid) return updated def replication_livecopy(options, args): """%(prog)s livecopy Load the contents of one glance instance into another. fromserver:port: the location of the master glance instance. toserver:port: the location of the slave glance instance. """ # Make sure from-server and to-server are provided if len(args) < 2: raise TypeError(_("Too few arguments.")) slave_server_port = args.pop() master_server_port = args.pop() if not re.match(SERVER_PORT_REGEX, slave_server_port) or \ not re.match(SERVER_PORT_REGEX, master_server_port): raise ValueError(_("Bad format of the given arguments.")) imageservice = get_image_service() slave_server, slave_port = slave_server_port.split(':') slave_conn = httplib.HTTPConnection(slave_server, slave_port) slave_client = imageservice(slave_conn, options.slavetoken) master_server, master_port = master_server_port.split(':') master_conn = httplib.HTTPConnection(master_server, master_port) master_client = imageservice(master_conn, options.mastertoken) updated = [] for image in master_client.get_images(): logging.info(_('Considering %(id)s') % {'id': image['id']}) for key in options.dontreplicate.split(' '): if key in image: logging.debug(_('Stripping %(header)s from master metadata'), {'header': key}) del image[key] if _image_present(slave_client, image['id']): # NOTE(mikal): Perhaps we just need to update the metadata? # Note that we don't attempt to change an image file once it # has been uploaded. headers = slave_client.get_image_meta(image['id']) if headers['status'] == 'active': for key in options.dontreplicate.split(' '): if key in image: logging.debug(_('Stripping %(header)s from master ' 'metadata'), {'header': key}) del image[key] if key in headers: logging.debug(_('Stripping %(header)s from slave ' 'metadata'), {'header': key}) del headers[key] if _dict_diff(image, headers): logging.info(_('... metadata has changed')) headers, body = slave_client.add_image_meta(image) _check_upload_response_headers(headers, body) updated.append(image['id']) elif image['status'] == 'active': logging.info(_('%s is being synced') % image['id']) if not options.metaonly: image_response = master_client.get_image(image['id']) try: headers, body = slave_client.add_image(image, image_response) _check_upload_response_headers(headers, body) updated.append(image['id']) except ImageAlreadyPresentException: logging.error(IMAGE_ALREADY_PRESENT_MESSAGE % image['id']) return updated def replication_compare(options, args): """%(prog)s compare Compare the contents of fromserver with those of toserver. fromserver:port: the location of the master glance instance. toserver:port: the location of the slave glance instance. """ # Make sure from-server and to-server are provided if len(args) < 2: raise TypeError(_("Too few arguments.")) slave_server_port = args.pop() master_server_port = args.pop() if not re.match(SERVER_PORT_REGEX, slave_server_port) or \ not re.match(SERVER_PORT_REGEX, master_server_port): raise ValueError(_("Bad format of the given arguments.")) imageservice = get_image_service() slave_server, slave_port = slave_server_port.split(':') slave_conn = httplib.HTTPConnection(slave_server, slave_port) slave_client = imageservice(slave_conn, options.slavetoken) master_server, master_port = master_server_port.split(':') master_conn = httplib.HTTPConnection(master_server, master_port) master_client = imageservice(master_conn, options.mastertoken) differences = {} for image in master_client.get_images(): if _image_present(slave_client, image['id']): headers = slave_client.get_image_meta(image['id']) for key in options.dontreplicate.split(' '): if key in image: logging.debug(_('Stripping %(header)s from master ' 'metadata'), {'header': key}) del image[key] if key in headers: logging.debug(_('Stripping %(header)s from slave ' 'metadata'), {'header': key}) del headers[key] for key in image: if image[key] != headers.get(key, None): logging.info(_('%(image_id)s: field %(key)s differs ' '(source is %(master_value)s, destination ' 'is %(slave_value)s)') % {'image_id': image['id'], 'key': key, 'master_value': image[key], 'slave_value': headers.get(key, 'undefined')}) differences[image['id']] = 'diff' else: logging.debug(_('%(image_id)s is identical') % {'image_id': image['id']}) elif image['status'] == 'active': logging.info(_('%s: entirely missing from the destination') % image['id']) differences[image['id']] = 'missing' return differences def _check_upload_response_headers(headers, body): """Check that the headers of an upload are reasonable. headers: the headers from the upload body: the body from the upload """ if 'status' not in headers: try: d = jsonutils.loads(body) if 'image' in d and 'status' in d['image']: return except Exception: raise UploadException('Image upload problem: %s' % body) def _image_present(client, image_uuid): """Check if an image is present in glance. client: the ImageService image_uuid: the image uuid to check Returns: True if the image is present """ headers = client.get_image_meta(image_uuid) return 'status' in headers def parse_options(parser, cli_args): """Returns the parsed CLI options, command to run and its arguments, merged with any same-named options found in a configuration file parser: the option parser cli_args: the arguments passed on the command line Returns: a tuple of (the parsed options, the command, the command name) """ if not cli_args: cli_args.append('-h') # Show options in usage output... (options, args) = parser.parse_args(cli_args) # HACK(sirp): Make the parser available to the print_help method # print_help is a command, so it only accepts (options, args); we could # one-off have it take (parser, options, args), however, for now, I think # this little hack will suffice options.__parser = parser if not args: parser.print_usage() sys.exit(0) command_name = args.pop(0) command = lookup_command(parser, command_name) return (options, command, args) def print_help(options, args): """Print help specific to a command. options: the parsed command line options args: the command line """ if len(args) != 1: print(COMMANDS) sys.exit(1) parser = options.__parser command_name = args.pop() command = lookup_command(parser, command_name) print(command.__doc__ % {'prog': os.path.basename(sys.argv[0])}) def lookup_command(parser, command_name): """Lookup a command. parser: the command parser command_name: the command name Returns: a method which implements that command """ BASE_COMMANDS = {'help': print_help} REPLICATION_COMMANDS = {'compare': replication_compare, 'dump': replication_dump, 'livecopy': replication_livecopy, 'load': replication_load, 'size': replication_size} commands = {} for command_set in (BASE_COMMANDS, REPLICATION_COMMANDS): commands.update(command_set) try: command = commands[command_name] except KeyError: parser.print_usage() sys.exit(_("Unknown command: %s") % command_name) return command def logging_excepthook(type, value, tb): extra = {} extra['exc_info'] = (type, value, tb) logging.critical(str(value), **extra) def main(): """The main function.""" usage = """ %%prog [options] [args] %s """ % COMMANDS oparser = optparse.OptionParser(usage=usage.strip()) # Options oparser.add_option('-c', '--chunksize', action="store", default=65536, help="Amount of data to transfer per HTTP write.") oparser.add_option('-d', '--debug', action="store_true", default=False, help="Print debugging information.") oparser.add_option('-D', '--dontreplicate', action="store", default=('created_at date deleted_at location ' 'updated_at'), help="List of fields to not replicate.") oparser.add_option('-m', '--metaonly', action="store_true", default=False, help="Only replicate metadata, not images.") oparser.add_option('-l', '--logfile', action="store", default='', help="Path of file to log to.") oparser.add_option('-s', '--syslog', action="store_true", default=False, help="Log to syslog instead of a file.") oparser.add_option('-t', '--token', action="store", default='', help=("Pass in your authentication token if you have " "one. If you use this option the same token is " "used for both the master and the slave.")) oparser.add_option('-M', '--mastertoken', action="store", default='', help=("Pass in your authentication token if you have " "one. This is the token used for the master.")) oparser.add_option('-S', '--slavetoken', action="store", default='', help=("Pass in your authentication token if you have " "one. This is the token used for the slave.")) oparser.add_option('-v', '--verbose', action="store_true", default=False, help="Print more verbose output.") (options, command, args) = parse_options(oparser, sys.argv[1:]) # Setup logging root_logger = logging.root if options.debug: root_logger.setLevel(logging.DEBUG) elif options.verbose: root_logger.setLevel(logging.INFO) else: root_logger.setLevel(logging.WARNING) formatter = logging.Formatter() if options.syslog: handler = logging.handlers.SysLogHandler(address='/dev/log') elif options.logfile: handler = logging.handlers.WatchedFileHandler(options.logfile) else: handler = logging.StreamHandler(sys.stdout) sys.excepthook = logging_excepthook if options.token: options.slavetoken = options.token options.mastertoken = options.token handler.setFormatter(formatter) root_logger.addHandler(handler) try: command(options, args) except TypeError as e: logging.error(command.__doc__ % {'prog': command.__name__}) sys.exit("ERROR: %s" % e) except ValueError as e: logging.error(command.__doc__ % {'prog': command.__name__}) sys.exit("ERROR: %s" % e) except Exception as e: raise if __name__ == '__main__': main() glance-2014.1/glance/cmd/cache_cleaner.py0000664000175400017540000000400012323736226021272 0ustar jenkinsjenkins00000000000000# Copyright 2010 United States Government as represented by the # Administrator of the National Aeronautics and Space Administration. # Copyright 2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ Glance Image Cache Invalid Cache Entry and Stalled Image cleaner This is meant to be run as a periodic task from cron. If something goes wrong while we're caching an image (for example the fetch times out, or an exception is raised), we create an 'invalid' entry. These entires are left around for debugging purposes. However, after some period of time, we want to clean these up. Also, if an incomplete image hangs around past the image_cache_stall_time period, we automatically sweep it up. """ 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) from glance.common import config from glance.image_cache import cleaner from glance.openstack.common import log def main(): try: config.parse_cache_args() log.setup('glance') app = cleaner.Cleaner() app.run() except RuntimeError as e: sys.exit("ERROR: %s" % e) glance-2014.1/glance/cmd/cache_pruner.py0000664000175400017540000000315512323736226021206 0ustar jenkinsjenkins00000000000000# Copyright 2010 United States Government as represented by the # Administrator of the National Aeronautics and Space Administration. # Copyright 2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ Glance Image Cache Pruner This is meant to be run as a periodic task, perhaps every half-hour. """ 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) from glance.common import config from glance.image_cache import pruner from glance.openstack.common import log def main(): try: config.parse_cache_args() log.setup('glance') app = pruner.Pruner() app.run() except RuntimeError as e: sys.exit("ERROR: %s" % e) glance-2014.1/glance/cmd/control.py0000664000175400017540000003141512323736226020230 0ustar jenkinsjenkins00000000000000# Copyright (c) 2011 OpenStack Foundation # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # implied. # See the License for the specific language governing permissions and # limitations under the License. """ Helper script for starting/stopping/reloading Glance server programs. Thanks for some of the code, Swifties ;) """ from __future__ import print_function from __future__ import with_statement import argparse import fcntl import os import resource import signal import subprocess import sys import tempfile import time # 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) from oslo.config import cfg from six.moves import xrange from glance.common import config from glance.openstack.common import units CONF = cfg.CONF ALL_COMMANDS = ['start', 'status', 'stop', 'shutdown', 'restart', 'reload', 'force-reload'] ALL_SERVERS = ['api', 'registry', 'scrubber'] GRACEFUL_SHUTDOWN_SERVERS = ['glance-api', 'glance-registry', 'glance-scrubber'] MAX_DESCRIPTORS = 32768 MAX_MEMORY = 2 * units.Gi # 2 GB USAGE = """%(prog)s [options] [CONFPATH] Where is one of: all, {0} And command is one of: {1} And CONFPATH is the optional configuration file to use.""".\ format(', '.join(ALL_SERVERS), ', '.join(ALL_COMMANDS)) exitcode = 0 def gated_by(predicate): def wrap(f): def wrapped_f(*args): if predicate: return f(*args) else: return None return wrapped_f return wrap def pid_files(server, pid_file): pid_files = [] if pid_file: if os.path.exists(os.path.abspath(pid_file)): pid_files = [os.path.abspath(pid_file)] else: if os.path.exists('/var/run/glance/%s.pid' % server): pid_files = ['/var/run/glance/%s.pid' % server] for pid_file in pid_files: pid = int(open(pid_file).read().strip()) yield pid_file, pid def do_start(verb, pid_file, server, args): if verb != 'Respawn' and pid_file == CONF.pid_file: for pid_file, pid in pid_files(server, pid_file): if os.path.exists('/proc/%s' % pid): print(_("%(serv)s appears to already be running: %(pid)s") % {'serv': server, 'pid': pid_file}) return else: print(_("Removing stale pid file %s") % pid_file) os.unlink(pid_file) try: resource.setrlimit(resource.RLIMIT_NOFILE, (MAX_DESCRIPTORS, MAX_DESCRIPTORS)) resource.setrlimit(resource.RLIMIT_DATA, (MAX_MEMORY, MAX_MEMORY)) except ValueError: print(_('Unable to increase file descriptor limit. ' 'Running as non-root?')) os.environ['PYTHON_EGG_CACHE'] = '/tmp' def write_pid_file(pid_file, pid): fp = open(pid_file, 'w') fp.write('%d\n' % pid) fp.close() def redirect_to_null(fds): with open(os.devnull, 'r+b') as nullfile: for desc in fds: # close fds try: os.dup2(nullfile.fileno(), desc) except OSError: pass def redirect_to_syslog(fds, server): log_cmd = 'logger -t "%s[%d]"' % (server, os.getpid()) process = subprocess.Popen(log_cmd, shell=True, stdin=subprocess.PIPE) for desc in fds: # pipe to logger command try: os.dup2(process.stdin.fileno(), desc) except OSError: pass def redirect_stdio(server, capture_output): input = [sys.stdin.fileno()] output = [sys.stdout.fileno(), sys.stderr.fileno()] redirect_to_null(input) if capture_output: redirect_to_syslog(output, server) else: redirect_to_null(output) @gated_by(CONF.capture_output) def close_stdio_on_exec(): fds = [sys.stdin.fileno(), sys.stdout.fileno(), sys.stderr.fileno()] for desc in fds: # set close on exec flag fcntl.fcntl(desc, fcntl.F_SETFD, fcntl.FD_CLOEXEC) def launch(pid_file, conf_file=None, capture_output=False, await_time=0): args = [server] msg = (_('%(verb)sing %(serv)s') % {'verb': verb, 'serv': server}) if conf_file: args += ['--config-file', conf_file] msg += 'with %s' % conf_file print(msg) close_stdio_on_exec() pid = os.fork() if pid == 0: os.setsid() redirect_stdio(server, capture_output) try: os.execlp('%s' % server, *args) except OSError as e: msg = (_('unable to launch %(serv)s. Got error: %(e)s') % {'serv': server, 'e': e}) sys.exit(msg) sys.exit(0) else: write_pid_file(pid_file, pid) await_child(pid, await_time) return pid @gated_by(CONF.await_child) def await_child(pid, await_time): bail_time = time.time() + await_time while time.time() < bail_time: reported_pid, status = os.waitpid(pid, os.WNOHANG) if reported_pid == pid: global exitcode exitcode = os.WEXITSTATUS(status) break time.sleep(0.05) conf_file = None if args and os.path.exists(args[0]): conf_file = os.path.abspath(os.path.expanduser(args[0])) return launch(pid_file, conf_file, CONF.capture_output, CONF.await_child) def do_check_status(pid_file, server): if os.path.exists(pid_file): pid = open(pid_file).read().strip() print(_("%(serv)s (pid %(pid)s) is running...") % {'serv': server, 'pid': pid}) else: print(_("%s is stopped") % server) def get_pid_file(server, pid_file): pid_file = (os.path.abspath(pid_file) if pid_file else '/var/run/glance/%s.pid' % server) dir, file = os.path.split(pid_file) if not os.path.exists(dir): try: os.makedirs(dir) except OSError: pass if not os.access(dir, os.W_OK): fallback = os.path.join(tempfile.mkdtemp(), '%s.pid' % server) msg = (_('Unable to create pid file %(pid)s. Running as non-root?\n' 'Falling back to a temp file, you can stop %(service)s ' 'service using:\n' ' %(file)s %(server)s stop --pid-file %(fb)s') % {'pid': pid_file, 'service': server, 'file': __file__, 'server': server, 'fb': fallback}) print(msg) pid_file = fallback return pid_file def do_stop(server, args, graceful=False): if graceful and server in GRACEFUL_SHUTDOWN_SERVERS: sig = signal.SIGHUP else: sig = signal.SIGTERM did_anything = False pfiles = pid_files(server, CONF.pid_file) for pid_file, pid in pfiles: did_anything = True try: os.unlink(pid_file) except OSError: pass try: print(_('Stopping %(serv)s (pid %(pid)s) with signal(%(sig)s)') % {'serv': server, 'pid': pid, 'sig': sig}) os.kill(pid, sig) except OSError: print(_("Process %d not running") % pid) for pid_file, pid in pfiles: for _junk in xrange(150): # 15 seconds if not os.path.exists('/proc/%s' % pid): break time.sleep(0.1) else: print(_('Waited 15 seconds for pid %(pid)s (%(file)s) to die;' ' giving up') % {'pid': pid, 'file': pid_file}) if not did_anything: print(_('%s is already stopped') % server) def add_command_parsers(subparsers): cmd_parser = argparse.ArgumentParser(add_help=False) cmd_subparsers = cmd_parser.add_subparsers(dest='command') for cmd in ALL_COMMANDS: parser = cmd_subparsers.add_parser(cmd) parser.add_argument('args', nargs=argparse.REMAINDER) for server in ALL_SERVERS: full_name = 'glance-' + server parser = subparsers.add_parser(server, parents=[cmd_parser]) parser.set_defaults(servers=[full_name]) parser = subparsers.add_parser(full_name, parents=[cmd_parser]) parser.set_defaults(servers=[full_name]) parser = subparsers.add_parser('all', parents=[cmd_parser]) parser.set_defaults(servers=['glance-' + s for s in ALL_SERVERS]) def main(): global exitcode opts = [ cfg.SubCommandOpt('server', title='Server types', help='Available server types', handler=add_command_parsers), cfg.StrOpt('pid-file', metavar='PATH', help='File to use as pid file. Default: ' '/var/run/glance/$server.pid.'), cfg.IntOpt('await-child', metavar='DELAY', default=0, help='Period to wait for service death ' 'in order to report exit code ' '(default is to not wait at all).'), cfg.BoolOpt('capture-output', default=False, help='Capture stdout/err in syslog ' 'instead of discarding it.'), cfg.BoolOpt('respawn', default=False, help='Restart service on unexpected death.'), ] CONF.register_cli_opts(opts) config.parse_args(usage=USAGE) @gated_by(CONF.await_child) @gated_by(CONF.respawn) def mutually_exclusive(): sys.stderr.write('--await-child and --respawn are mutually exclusive') sys.exit(1) mutually_exclusive() @gated_by(CONF.respawn) def anticipate_respawn(children): while children: pid, status = os.wait() if pid in children: (pid_file, server, args) = children.pop(pid) running = os.path.exists(pid_file) one_second_ago = time.time() - 1 bouncing = (running and os.path.getmtime(pid_file) >= one_second_ago) if running and not bouncing: args = (pid_file, server, args) new_pid = do_start('Respawn', *args) children[new_pid] = args else: rsn = 'bouncing' if bouncing else 'deliberately stopped' print(_('Supressed respawn as %(serv)s was %(rsn)s.') % {'serv': server, 'rsn': rsn}) if CONF.server.command == 'start': children = {} for server in CONF.server.servers: pid_file = get_pid_file(server, CONF.pid_file) args = (pid_file, server, CONF.server.args) pid = do_start('Start', *args) children[pid] = args anticipate_respawn(children) if CONF.server.command == 'status': for server in CONF.server.servers: pid_file = get_pid_file(server, CONF.pid_file) do_check_status(pid_file, server) if CONF.server.command == 'stop': for server in CONF.server.servers: do_stop(server, CONF.server.args) if CONF.server.command == 'shutdown': for server in CONF.server.servers: do_stop(server, CONF.server.args, graceful=True) if CONF.server.command == 'restart': for server in CONF.server.servers: do_stop(server, CONF.server.args) for server in CONF.server.servers: pid_file = get_pid_file(server, CONF.pid_file) do_start('Restart', pid_file, server, CONF.server.args) if (CONF.server.command == 'reload' or CONF.server.command == 'force-reload'): for server in CONF.server.servers: do_stop(server, CONF.server.args, graceful=True) pid_file = get_pid_file(server, CONF.pid_file) do_start('Restart', pid_file, server, CONF.server.args) sys.exit(exitcode) glance-2014.1/glance/cmd/api.py0000775000175400017540000000422012323736226017316 0ustar jenkinsjenkins00000000000000#!/usr/bin/env python # Copyright 2010 United States Government as represented by the # Administrator of the National Aeronautics and Space Administration. # Copyright 2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ Glance API Server """ import eventlet import os import sys import six # Monkey patch socket, time, select, threads eventlet.patcher.monkey_patch(all=False, socket=True, time=True, select=True, thread=True) # 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) from glance.common import config from glance.common import exception from glance.common import wsgi from glance.openstack.common import log import glance.store def fail(returncode, e): sys.stderr.write("ERROR: %s\n" % six.text_type(e)) sys.exit(returncode) def main(): try: config.parse_args() log.setup('glance') glance.store.create_stores() glance.store.verify_default_store() server = wsgi.Server() server.start(config.load_paste_app('glance-api'), default_port=9292) server.wait() except exception.WorkerCreationFailure as e: fail(2, e) except RuntimeError as e: fail(1, e) if __name__ == '__main__': main() glance-2014.1/glance/cmd/scrubber.py0000775000175400017540000000456612323736226020371 0ustar jenkinsjenkins00000000000000#!/usr/bin/env python # Copyright 2011-2012 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ Glance Scrub Service """ 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) from oslo.config import cfg from glance.common import config from glance.openstack.common import log from glance import scrubber import glance.store CONF = cfg.CONF def main(): CONF.register_cli_opt( cfg.BoolOpt('daemon', short='D', default=False, help='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.')) CONF.register_opt(cfg.IntOpt('wakeup_time', default=300)) try: config.parse_args() log.setup('glance') glance.store.create_stores() glance.store.verify_default_store() app = scrubber.Scrubber(glance.store) if CONF.daemon: server = scrubber.Daemon(CONF.wakeup_time) server.start(app) server.wait() else: import eventlet pool = eventlet.greenpool.GreenPool(1000) app.run(pool) except RuntimeError as e: sys.exit("ERROR: %s" % e) if __name__ == '__main__': main() glance-2014.1/glance/cmd/cache_prefetcher.py0000775000175400017540000000326112323736226022023 0ustar jenkinsjenkins00000000000000#!/usr/bin/env python # Copyright 2011-2012 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ Glance Image Cache Pre-fetcher This is meant to be run from the command line after queueing images to be pretched. """ 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) from glance.common import config from glance.image_cache import prefetcher from glance.openstack.common import log import glance.store def main(): try: config.parse_cache_args() log.setup('glance') glance.store.create_stores() glance.store.verify_default_store() app = prefetcher.Prefetcher() app.run() except RuntimeError as e: sys.exit("ERROR: %s" % e) if __name__ == '__main__': main() glance-2014.1/glance/cmd/registry.py0000775000175400017540000000353512323736226020425 0ustar jenkinsjenkins00000000000000#!/usr/bin/env python # Copyright 2010 United States Government as represented by the # Administrator of the National Aeronautics and Space Administration. # Copyright 2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ Reference implementation server for Glance Registry """ import eventlet import os import sys # Monkey patch socket and time eventlet.patcher.monkey_patch(all=False, socket=True, time=True, thread=True) # 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) from glance.common import config from glance.common import wsgi from glance.openstack.common import log def main(): try: config.parse_args() log.setup('glance') server = wsgi.Server() server.start(config.load_paste_app('glance-registry'), default_port=9191) server.wait() except RuntimeError as e: sys.exit("ERROR: %s" % e) if __name__ == '__main__': main() glance-2014.1/glance/cmd/__init__.py0000664000175400017540000000132712323736226020306 0ustar jenkinsjenkins00000000000000# Copyright 2013 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from glance.openstack.common import gettextutils gettextutils.install('glance', lazy=True) glance-2014.1/glance/version.py0000664000175400017540000000125612323736226017472 0ustar jenkinsjenkins00000000000000# Copyright 2012 OpenStack Foundation # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import pbr.version version_info = pbr.version.VersionInfo('glance') glance-2014.1/glance/gateway.py0000664000175400017540000001161012323736226017441 0ustar jenkinsjenkins00000000000000# Copyright 2012 OpenStack Foundation # Copyright 2013 IBM Corp. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from glance.api import authorization from glance.api import policy from glance.api import property_protections from glance.common import property_utils import glance.db import glance.domain import glance.notifier import glance.quota import glance.store class Gateway(object): def __init__(self, db_api=None, store_api=None, notifier=None, policy_enforcer=None): self.db_api = db_api or glance.db.get_api() self.store_api = store_api or glance.store self.notifier = notifier or glance.notifier.Notifier() self.policy = policy_enforcer or policy.Enforcer() def get_image_factory(self, context): image_factory = glance.domain.ImageFactory() store_image_factory = glance.store.ImageFactoryProxy( image_factory, context, self.store_api) quota_image_factory = glance.quota.ImageFactoryProxy( store_image_factory, context, self.db_api) policy_image_factory = policy.ImageFactoryProxy( quota_image_factory, context, self.policy) notifier_image_factory = glance.notifier.ImageFactoryProxy( policy_image_factory, context, self.notifier) if property_utils.is_property_protection_enabled(): property_rules = property_utils.PropertyRules(self.policy) protected_image_factory = property_protections.\ ProtectedImageFactoryProxy(notifier_image_factory, context, property_rules) authorized_image_factory = authorization.ImageFactoryProxy( protected_image_factory, context) else: authorized_image_factory = authorization.ImageFactoryProxy( notifier_image_factory, context) return authorized_image_factory def get_image_member_factory(self, context): image_factory = glance.domain.ImageMemberFactory() quota_image_factory = glance.quota.ImageMemberFactoryProxy( image_factory, context, self.db_api) policy_member_factory = policy.ImageMemberFactoryProxy( quota_image_factory, context, self.policy) authorized_image_factory = authorization.ImageMemberFactoryProxy( policy_member_factory, context) return authorized_image_factory def get_repo(self, context): image_repo = glance.db.ImageRepo(context, self.db_api) store_image_repo = glance.store.ImageRepoProxy( image_repo, context, self.store_api) quota_image_repo = glance.quota.ImageRepoProxy( store_image_repo, context, self.db_api) policy_image_repo = policy.ImageRepoProxy( quota_image_repo, context, self.policy) notifier_image_repo = glance.notifier.ImageRepoProxy( policy_image_repo, context, self.notifier) if property_utils.is_property_protection_enabled(): property_rules = property_utils.PropertyRules(self.policy) protected_image_repo = property_protections.\ ProtectedImageRepoProxy(notifier_image_repo, context, property_rules) authorized_image_repo = authorization.ImageRepoProxy( protected_image_repo, context) else: authorized_image_repo = authorization.ImageRepoProxy( notifier_image_repo, context) return authorized_image_repo def get_task_factory(self, context): task_factory = glance.domain.TaskFactory() policy_task_factory = policy.TaskFactoryProxy( task_factory, context, self.policy) notifier_task_factory = glance.notifier.TaskFactoryProxy( policy_task_factory, context, self.notifier) authorized_task_factory = authorization.TaskFactoryProxy( notifier_task_factory, context) return authorized_task_factory def get_task_repo(self, context): task_repo = glance.db.TaskRepo(context, self.db_api) policy_task_repo = policy.TaskRepoProxy( task_repo, context, self.policy) notifier_task_repo = glance.notifier.TaskRepoProxy( policy_task_repo, context, self.notifier) authorized_task_repo = authorization.TaskRepoProxy( notifier_task_repo, context) return authorized_task_repo glance-2014.1/glance/api/0000775000175400017540000000000012323736427016203 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/api/authorization.py0000664000175400017540000003517312323736230021456 0ustar jenkinsjenkins00000000000000# Copyright 2012 OpenStack Foundation # Copyright 2013 IBM Corp. # 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 copy from glance.common import exception import glance.domain.proxy def is_image_mutable(context, image): """Return True if the image is mutable in this context.""" if context.is_admin: return True if image.owner is None or context.owner is None: return False return image.owner == context.owner def proxy_image(context, image): if is_image_mutable(context, image): return ImageProxy(image, context) else: return ImmutableImageProxy(image, context) def is_member_mutable(context, member): """Return True if the image is mutable in this context.""" if context.is_admin: return True if context.owner is None: return False return member.member_id == context.owner def proxy_member(context, member): if is_member_mutable(context, member): return member else: return ImmutableMemberProxy(member) def is_task_mutable(context, task): """Return True if the task is mutable in this context.""" if context.is_admin: return True if context.owner is None: return False return task.owner == context.owner def proxy_task(context, task): if is_task_mutable(context, task): return task else: return ImmutableTaskProxy(task) def proxy_task_details(context, task, task_details): if is_task_mutable(context, task): return task_details else: return ImmutableTaskDetailsProxy(task_details) class ImageRepoProxy(glance.domain.proxy.Repo): def __init__(self, image_repo, context): self.context = context self.image_repo = image_repo proxy_kwargs = {'context': self.context} super(ImageRepoProxy, self).__init__(image_repo, item_proxy_class=ImageProxy, item_proxy_kwargs=proxy_kwargs) def get(self, image_id): image = self.image_repo.get(image_id) return proxy_image(self.context, image) def list(self, *args, **kwargs): images = self.image_repo.list(*args, **kwargs) return [proxy_image(self.context, i) for i in images] class ImageMemberRepoProxy(glance.domain.proxy.Repo): def __init__(self, member_repo, image, context): self.member_repo = member_repo self.image = image self.context = context super(ImageMemberRepoProxy, self).__init__(member_repo) def get(self, member_id): if (self.context.is_admin or self.context.owner == self.image.owner or self.context.owner == member_id): member = self.member_repo.get(member_id) return proxy_member(self.context, member) else: message = _("You cannot get image member for %s") raise exception.Forbidden(message % member_id) def list(self, *args, **kwargs): members = self.member_repo.list(*args, **kwargs) if (self.context.is_admin or self.context.owner == self.image.owner): return [proxy_member(self.context, m) for m in members] for member in members: if member.member_id == self.context.owner: return [proxy_member(self.context, member)] message = _("You cannot get image member for %s") raise exception.Forbidden(message % self.image.image_id) def remove(self, image_member): if (self.image.owner == self.context.owner or self.context.is_admin): self.member_repo.remove(image_member) else: message = _("You cannot delete image member for %s") raise exception.Forbidden(message % self.image.image_id) def add(self, image_member): if (self.image.owner == self.context.owner or self.context.is_admin): self.member_repo.add(image_member) else: message = _("You cannot add image member for %s") raise exception.Forbidden(message % self.image.image_id) def save(self, image_member): if (self.context.is_admin or self.context.owner == image_member.member_id): self.member_repo.save(image_member) else: message = _("You cannot update image member %s") raise exception.Forbidden(message % image_member.member_id) class ImageFactoryProxy(glance.domain.proxy.ImageFactory): def __init__(self, image_factory, context): self.image_factory = image_factory self.context = context kwargs = {'context': self.context} super(ImageFactoryProxy, self).__init__(image_factory, proxy_class=ImageProxy, proxy_kwargs=kwargs) def new_image(self, **kwargs): owner = kwargs.pop('owner', self.context.owner) if not self.context.is_admin: if owner is None or owner != self.context.owner: message = _("You are not permitted to create images " "owned by '%s'.") raise exception.Forbidden(message % owner) return super(ImageFactoryProxy, self).new_image(owner=owner, **kwargs) class ImageMemberFactoryProxy(object): def __init__(self, image_member_factory, context): self.image_member_factory = image_member_factory self.context = context def new_image_member(self, image, member_id): owner = image.owner if not self.context.is_admin: if owner is None or owner != self.context.owner: message = _("You are not permitted to create image members " "for the image.") raise exception.Forbidden(message) if image.visibility == 'public': message = _("Public images do not have members.") raise exception.Forbidden(message) return self.image_member_factory.new_image_member(image, member_id) def _immutable_attr(target, attr, proxy=None): def get_attr(self): value = getattr(getattr(self, target), attr) if proxy is not None: value = proxy(value) return value def forbidden(self, *args, **kwargs): resource = getattr(self, 'resource_name', 'resource') message = _("You are not permitted to modify '%(attr)s' on this " "%(resource)s.") raise exception.Forbidden(message % {'attr': attr, 'resource': resource}) return property(get_attr, forbidden, forbidden) class ImmutableLocations(list): def forbidden(self, *args, **kwargs): message = _("You are not permitted to modify locations " "for this image.") raise exception.Forbidden(message) def __deepcopy__(self, memo): return ImmutableLocations(copy.deepcopy(list(self), memo)) append = forbidden extend = forbidden insert = forbidden pop = forbidden remove = forbidden reverse = forbidden sort = forbidden __delitem__ = forbidden __delslice__ = forbidden __iadd__ = forbidden __imul__ = forbidden __setitem__ = forbidden __setslice__ = forbidden class ImmutableProperties(dict): def forbidden_key(self, key, *args, **kwargs): message = _("You are not permitted to modify '%s' on this image.") raise exception.Forbidden(message % key) def forbidden(self, *args, **kwargs): message = _("You are not permitted to modify this image.") raise exception.Forbidden(message) __delitem__ = forbidden_key __setitem__ = forbidden_key pop = forbidden popitem = forbidden setdefault = forbidden update = forbidden class ImmutableTags(set): def forbidden(self, *args, **kwargs): message = _("You are not permitted to modify tags on this image.") raise exception.Forbidden(message) add = forbidden clear = forbidden difference_update = forbidden intersection_update = forbidden pop = forbidden remove = forbidden symmetric_difference_update = forbidden update = forbidden class ImmutableImageProxy(object): def __init__(self, base, context): self.base = base self.context = context self.resource_name = 'image' name = _immutable_attr('base', 'name') image_id = _immutable_attr('base', 'image_id') name = _immutable_attr('base', 'name') status = _immutable_attr('base', 'status') created_at = _immutable_attr('base', 'created_at') updated_at = _immutable_attr('base', 'updated_at') visibility = _immutable_attr('base', 'visibility') min_disk = _immutable_attr('base', 'min_disk') min_ram = _immutable_attr('base', 'min_ram') protected = _immutable_attr('base', 'protected') locations = _immutable_attr('base', 'locations', proxy=ImmutableLocations) checksum = _immutable_attr('base', 'checksum') owner = _immutable_attr('base', 'owner') disk_format = _immutable_attr('base', 'disk_format') container_format = _immutable_attr('base', 'container_format') size = _immutable_attr('base', 'size') virtual_size = _immutable_attr('base', 'virtual_size') extra_properties = _immutable_attr('base', 'extra_properties', proxy=ImmutableProperties) tags = _immutable_attr('base', 'tags', proxy=ImmutableTags) def delete(self): message = _("You are not permitted to delete this image.") raise exception.Forbidden(message) def get_member_repo(self): member_repo = self.base.get_member_repo() return ImageMemberRepoProxy(member_repo, self, self.context) def get_data(self): return self.base.get_data() def set_data(self, *args, **kwargs): message = _("You are not permitted to upload data for this image.") raise exception.Forbidden(message) class ImmutableMemberProxy(object): def __init__(self, base): self.base = base self.resource_name = 'image member' id = _immutable_attr('base', 'id') image_id = _immutable_attr('base', 'image_id') member_id = _immutable_attr('base', 'member_id') status = _immutable_attr('base', 'status') created_at = _immutable_attr('base', 'created_at') updated_at = _immutable_attr('base', 'updated_at') class ImmutableTaskProxy(object): def __init__(self, base): self.base = base self.resource_name = 'task' task_id = _immutable_attr('base', 'task_id') type = _immutable_attr('base', 'type') status = _immutable_attr('base', 'status') owner = _immutable_attr('base', 'owner') expires_at = _immutable_attr('base', 'expires_at') created_at = _immutable_attr('base', 'created_at') updated_at = _immutable_attr('base', 'updated_at') def run(self, executor): self.base.run(executor) def begin_processing(self): message = _("You are not permitted to set status on this task.") raise exception.Forbidden(message) def succeed(self, result): message = _("You are not permitted to set status on this task.") raise exception.Forbidden(message) def fail(self, message): message = _("You are not permitted to set status on this task.") raise exception.Forbidden(message) class ImmutableTaskDetailsProxy(object): def __init__(self, base): self.base = base input = _immutable_attr('base', 'input') message = _immutable_attr('base', 'message') result = _immutable_attr('base', 'result') class ImageProxy(glance.domain.proxy.Image): def __init__(self, image, context): self.image = image self.context = context super(ImageProxy, self).__init__(image) def get_member_repo(self, **kwargs): if self.image.visibility == 'public': message = _("Public images do not have members.") raise exception.Forbidden(message) else: member_repo = self.image.get_member_repo(**kwargs) return ImageMemberRepoProxy(member_repo, self, self.context) class TaskProxy(glance.domain.proxy.Task): def __init__(self, task): self.task = task super(TaskProxy, self).__init__(task) class TaskDetailsProxy(glance.domain.proxy.TaskDetails): def __init__(self, task_details): self.task_details = task_details super(TaskDetailsProxy, self).__init__(task_details) class TaskFactoryProxy(glance.domain.proxy.TaskFactory): def __init__(self, task_factory, context): self.task_factory = task_factory self.context = context super(TaskFactoryProxy, self).__init__( task_factory, task_proxy_class=TaskProxy, task_details_proxy_class=TaskDetailsProxy) def new_task(self, **kwargs): owner = kwargs.get('owner', self.context.owner) #NOTE(nikhil): Unlike Images, Tasks are expected to have owner. # We currently do not allow even admins to set the owner to None. if owner is not None and (owner == self.context.owner or self.context.is_admin): return super(TaskFactoryProxy, self).new_task(**kwargs) else: message = _("You are not permitted to create this task with " "owner as: %s") raise exception.Forbidden(message % owner) class TaskRepoProxy(glance.domain.proxy.TaskRepo): def __init__(self, task_repo, context): self.task_repo = task_repo self.context = context super(TaskRepoProxy, self).__init__(task_repo) def get_task_and_details(self, task_id): task, task_details = self.task_repo.get_task_and_details(task_id) return proxy_task(self.context, task), proxy_task_details(self.context, task, task_details) def list_tasks(self, *args, **kwargs): tasks = self.task_repo.list_tasks(*args, **kwargs) return [proxy_task(self.context, t) for t in tasks] glance-2014.1/glance/api/cached_images.py0000664000175400017540000000677412323736226021324 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ Controller for Image Cache Management API """ import webob.exc from glance.api import policy from glance.api.v1 import controller from glance.common import exception from glance.common import wsgi from glance import image_cache class Controller(controller.BaseController): """ A controller for managing cached images. """ def __init__(self): self.cache = image_cache.ImageCache() self.policy = policy.Enforcer() def _enforce(self, req): """Authorize request against 'manage_image_cache' policy""" try: self.policy.enforce(req.context, 'manage_image_cache', {}) except exception.Forbidden: raise webob.exc.HTTPForbidden() def get_cached_images(self, req): """ GET /cached_images Returns a mapping of records about cached images. """ self._enforce(req) images = self.cache.get_cached_images() return dict(cached_images=images) def delete_cached_image(self, req, image_id): """ DELETE /cached_images/ Removes an image from the cache. """ self._enforce(req) self.cache.delete_cached_image(image_id) def delete_cached_images(self, req): """ DELETE /cached_images - Clear all active cached images Removes all images from the cache. """ self._enforce(req) return dict(num_deleted=self.cache.delete_all_cached_images()) def get_queued_images(self, req): """ GET /queued_images Returns a mapping of records about queued images. """ self._enforce(req) images = self.cache.get_queued_images() return dict(queued_images=images) def queue_image(self, req, image_id): """ PUT /queued_images/ Queues an image for caching. We do not check to see if the image is in the registry here. That is done by the prefetcher... """ self._enforce(req) self.cache.queue_image(image_id) def delete_queued_image(self, req, image_id): """ DELETE /queued_images/ Removes an image from the cache. """ self._enforce(req) self.cache.delete_queued_image(image_id) def delete_queued_images(self, req): """ DELETE /queued_images - Clear all active queued images Removes all images from the cache. """ self._enforce(req) return dict(num_deleted=self.cache.delete_all_queued_images()) class CachedImageDeserializer(wsgi.JSONRequestDeserializer): pass class CachedImageSerializer(wsgi.JSONResponseSerializer): pass def create_resource(): """Cached Images resource factory method""" deserializer = CachedImageDeserializer() serializer = CachedImageSerializer() return wsgi.Resource(Controller(), deserializer, serializer) glance-2014.1/glance/api/middleware/0000775000175400017540000000000012323736427020320 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/api/middleware/context.py0000664000175400017540000001200612323736226022352 0ustar jenkinsjenkins00000000000000# Copyright 2011-2012 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from oslo.config import cfg import webob.exc from glance.api import policy from glance.common import wsgi import glance.context from glance.openstack.common import jsonutils import glance.openstack.common.log as logging context_opts = [ cfg.BoolOpt('owner_is_tenant', default=True, help=_('When true, this option sets the owner of an image ' 'to be the tenant. Otherwise, the owner of the ' ' image will be the authenticated user issuing the ' 'request.')), cfg.StrOpt('admin_role', default='admin', help=_('Role used to identify an authenticated user as ' 'administrator.')), cfg.BoolOpt('allow_anonymous_access', default=False, help=_('Allow unauthenticated users to access the API with ' 'read-only privileges. This only applies when using ' 'ContextMiddleware.')), ] CONF = cfg.CONF CONF.register_opts(context_opts) LOG = logging.getLogger(__name__) class BaseContextMiddleware(wsgi.Middleware): def process_response(self, resp): try: request_id = resp.request.context.request_id except AttributeError: LOG.warn(_('Unable to retrieve request id from context')) else: resp.headers['x-openstack-request-id'] = 'req-%s' % request_id return resp class ContextMiddleware(BaseContextMiddleware): def __init__(self, app): self.policy_enforcer = policy.Enforcer() super(ContextMiddleware, self).__init__(app) def process_request(self, req): """Convert authentication information into a request context Generate a glance.context.RequestContext object from the available authentication headers and store on the 'context' attribute of the req object. :param req: wsgi request object that will be given the context object :raises webob.exc.HTTPUnauthorized: when value of the X-Identity-Status header is not 'Confirmed' and anonymous access is disallowed """ if req.headers.get('X-Identity-Status') == 'Confirmed': req.context = self._get_authenticated_context(req) elif CONF.allow_anonymous_access: req.context = self._get_anonymous_context() else: raise webob.exc.HTTPUnauthorized() def _get_anonymous_context(self): kwargs = { 'user': None, 'tenant': None, 'roles': [], 'is_admin': False, 'read_only': True, 'policy_enforcer': self.policy_enforcer, } return glance.context.RequestContext(**kwargs) def _get_authenticated_context(self, req): #NOTE(bcwaldon): X-Roles is a csv string, but we need to parse # it into a list to be useful roles_header = req.headers.get('X-Roles', '') roles = [r.strip().lower() for r in roles_header.split(',')] #NOTE(bcwaldon): This header is deprecated in favor of X-Auth-Token deprecated_token = req.headers.get('X-Storage-Token') service_catalog = None if req.headers.get('X-Service-Catalog') is not None: try: catalog_header = req.headers.get('X-Service-Catalog') service_catalog = jsonutils.loads(catalog_header) except ValueError: raise webob.exc.HTTPInternalServerError( _('Invalid service catalog json.')) kwargs = { 'user': req.headers.get('X-User-Id'), 'tenant': req.headers.get('X-Tenant-Id'), 'roles': roles, 'is_admin': CONF.admin_role.strip().lower() in roles, 'auth_tok': req.headers.get('X-Auth-Token', deprecated_token), 'owner_is_tenant': CONF.owner_is_tenant, 'service_catalog': service_catalog, 'policy_enforcer': self.policy_enforcer, } return glance.context.RequestContext(**kwargs) class UnauthenticatedContextMiddleware(BaseContextMiddleware): def process_request(self, req): """Create a context without an authorized user.""" kwargs = { 'user': None, 'tenant': None, 'roles': [], 'is_admin': True, } req.context = glance.context.RequestContext(**kwargs) glance-2014.1/glance/api/middleware/cache_manage.py0000664000175400017540000000570312323736226023247 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ Image Cache Management API """ import routes from glance.api import cached_images from glance.common import wsgi import glance.openstack.common.log as logging LOG = logging.getLogger(__name__) class CacheManageFilter(wsgi.Middleware): def __init__(self, app): mapper = routes.Mapper() resource = cached_images.create_resource() 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 LOG.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_info, 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 glance-2014.1/glance/api/middleware/cache.py0000664000175400017540000002513612323736226021741 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ Transparent image file caching middleware, designed to live on Glance API nodes. When images are requested from the API node, this middleware caches the returned image file to local filesystem. When subsequent requests for the same image file are received, the local cached copy of the image file is returned. """ import re import webob from glance.api.common import size_checked_iter from glance.api import policy from glance.api.v1 import images from glance.common import exception from glance.common import utils from glance.common import wsgi import glance.db from glance import image_cache from glance import notifier import glance.openstack.common.log as logging import glance.registry.client.v1.api as registry LOG = logging.getLogger(__name__) PATTERNS = { ('v1', 'GET'): re.compile(r'^/v1/images/([^\/]+)$'), ('v1', 'DELETE'): re.compile(r'^/v1/images/([^\/]+)$'), ('v2', 'GET'): re.compile(r'^/v2/images/([^\/]+)/file$'), ('v2', 'DELETE'): re.compile(r'^/v2/images/([^\/]+)$') } class CacheFilter(wsgi.Middleware): def __init__(self, app): self.cache = image_cache.ImageCache() self.serializer = images.ImageSerializer() self.policy = policy.Enforcer() LOG.info(_("Initialized image cache middleware")) super(CacheFilter, self).__init__(app) def _verify_metadata(self, image_meta): """ Sanity check the 'deleted' and 'size' metadata values. """ # NOTE: admins can see image metadata in the v1 API, but shouldn't # be able to download the actual image data. if image_meta['deleted']: raise exception.NotFound() if not image_meta['size']: # override image size metadata with the actual cached # file size, see LP Bug #900959 image_meta['size'] = self.cache.get_image_size(image_meta['id']) @staticmethod def _match_request(request): """Determine the version of the url and extract the image id :returns tuple of version and image id if the url is a cacheable, otherwise None """ for ((version, method), pattern) in PATTERNS.items(): match = pattern.match(request.path_info) try: assert request.method == method image_id = match.group(1) # Ensure the image id we got looks like an image id to filter # out a URI like /images/detail. See LP Bug #879136 assert image_id != 'detail' except (AttributeError, AssertionError): continue else: return (version, method, image_id) def _enforce(self, req, action): """Authorize an action against our policies""" try: self.policy.enforce(req.context, action, {}) except exception.Forbidden as e: raise webob.exc.HTTPForbidden(explanation=unicode(e), request=req) def process_request(self, request): """ For requests for an image file, we check the local image cache. If present, we return the image file, appending the image metadata in headers. If not present, we pass the request on to the next application in the pipeline. """ match = self._match_request(request) try: (version, method, image_id) = match except TypeError: # Trying to unpack None raises this exception return None self._stash_request_info(request, image_id, method) if request.method != 'GET' or not self.cache.is_cached(image_id): return None try: self._enforce(request, 'download_image') except webob.exc.HTTPForbidden: return None LOG.debug(_("Cache hit for image '%s'"), image_id) image_iterator = self.get_from_cache(image_id) method = getattr(self, '_process_%s_request' % version) try: return method(request, image_id, image_iterator) except exception.NotFound: msg = _("Image cache contained image file for image '%s', " "however the registry did not contain metadata for " "that image!") % image_id LOG.error(msg) self.cache.delete_cached_image(image_id) @staticmethod def _stash_request_info(request, image_id, method): """ Preserve the image id and request method for later retrieval """ request.environ['api.cache.image_id'] = image_id request.environ['api.cache.method'] = method @staticmethod def _fetch_request_info(request): """ Preserve the cached image id for consumption by the process_response method of this middleware """ try: image_id = request.environ['api.cache.image_id'] method = request.environ['api.cache.method'] except KeyError: return None else: return (image_id, method) def _process_v1_request(self, request, image_id, image_iterator): image_meta = registry.get_image_metadata(request.context, image_id) # Don't display location if 'location' in image_meta: del image_meta['location'] image_meta.pop('location_data', None) self._verify_metadata(image_meta) response = webob.Response(request=request) raw_response = { 'image_iterator': image_iterator, 'image_meta': image_meta, } return self.serializer.show(response, raw_response) def _process_v2_request(self, request, image_id, image_iterator): # We do some contortions to get the image_metadata so # that we can provide it to 'size_checked_iter' which # will generate a notification. # TODO(mclaren): Make notification happen more # naturally once caching is part of the domain model. db_api = glance.db.get_api() image_repo = glance.db.ImageRepo(request.context, db_api) image = image_repo.get(image_id) image_meta = glance.notifier.format_image_notification(image) self._verify_metadata(image_meta) response = webob.Response(request=request) response.app_iter = size_checked_iter(response, image_meta, image_meta['size'], image_iterator, notifier.Notifier()) # NOTE (flwang): Set the content-type, content-md5 and content-length # explicitly to be consistent with the non-cache scenario. # Besides, it's not worth the candle to invoke the "download" method # of ResponseSerializer under image_data. Because method "download" # will reset the app_iter. Then we have to call method # "size_checked_iter" to avoid missing any notification. But after # call "size_checked_iter", we will lose the content-md5 and # content-length got by the method "download" because of this issue: # https://github.com/Pylons/webob/issues/86 response.headers['Content-Type'] = 'application/octet-stream' response.headers['Content-MD5'] = image.checksum response.headers['Content-Length'] = str(image.size) return response def process_response(self, resp): """ We intercept the response coming back from the main images Resource, removing image file from the cache if necessary """ status_code = self.get_status_code(resp) if not 200 <= status_code < 300: return resp try: (image_id, method) = self._fetch_request_info(resp.request) except TypeError: return resp if method == 'GET' and status_code == 204: # Bugfix:1251055 - Don't cache non-existent image files. # NOTE: Both GET for an image without locations and DELETE return # 204 but DELETE should be processed. return resp method_str = '_process_%s_response' % method try: process_response_method = getattr(self, method_str) except AttributeError: LOG.error(_('could not find %s') % method_str) # Nothing to do here, move along return resp else: return process_response_method(resp, image_id) def _process_DELETE_response(self, resp, image_id): if self.cache.is_cached(image_id): LOG.debug(_("Removing image %s from cache"), image_id) self.cache.delete_cached_image(image_id) return resp def _process_GET_response(self, resp, image_id): image_checksum = resp.headers.get('Content-MD5') if not image_checksum: # API V1 stores the checksum in a different header: image_checksum = resp.headers.get('x-image-meta-checksum') if not image_checksum: LOG.error(_("Checksum header is missing.")) # NOTE(zhiyan): image_cache return a generator object and set to # response.app_iter, it will be called by eventlet.wsgi later. # So we need enforce policy firstly but do it by application # since eventlet.wsgi could not catch webob.exc.HTTPForbidden and # return 403 error to client then. self._enforce(resp.request, 'download_image') resp.app_iter = self.cache.get_caching_iter(image_id, image_checksum, resp.app_iter) return resp def get_status_code(self, response): """ Returns the integer status code from the response, which can be either a Webob.Response (used in testing) or httplib.Response """ if hasattr(response, 'status_int'): return response.status_int return response.status def get_from_cache(self, image_id): """Called if cache hit""" with self.cache.open_for_read(image_id) as cache_file: chunks = utils.chunkiter(cache_file) for chunk in chunks: yield chunk glance-2014.1/glance/api/middleware/gzip.py0000664000175400017540000000431212323736226021640 0ustar jenkinsjenkins00000000000000# Copyright 2013 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. """ Use gzip compression if the client accepts it. """ import re from glance.common import wsgi import glance.openstack.common.log as logging LOG = logging.getLogger(__name__) class GzipMiddleware(wsgi.Middleware): re_zip = re.compile(r'\bgzip\b') def __init__(self, app): LOG.info(_("Initialized gzip middleware")) super(GzipMiddleware, self).__init__(app) def process_response(self, response): request = response.request accept_encoding = request.headers.get('Accept-Encoding', '') if self.re_zip.search(accept_encoding): # NOTE(flaper87): Webob removes the content-md5 when # app_iter is called. We'll keep it and reset it later checksum = response.headers.get("Content-MD5") # NOTE(flaper87): We'll use lazy for images so # that they can be compressed without reading # the whole content in memory. Notice that using # lazy will set response's content-length to 0. content_type = response.headers["Content-Type"] lazy = content_type == "application/octet-stream" # NOTE(flaper87): Webob takes care of the compression # process, it will replace the body either with a # compressed body or a generator - used for lazy com # pression - depending on the lazy value. # # Webob itself will set the Content-Encoding header. response.encode_content(lazy=lazy) if checksum: response.headers['Content-MD5'] = checksum return response glance-2014.1/glance/api/middleware/version_negotiation.py0000664000175400017540000000714112323736230024752 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ A filter middleware that inspects the requested URI for a version string and/or Accept headers and attempts to negotiate an API controller to return """ from oslo.config import cfg from glance.api import versions from glance.common import wsgi import glance.openstack.common.log as logging CONF = cfg.CONF LOG = logging.getLogger(__name__) class VersionNegotiationFilter(wsgi.Middleware): def __init__(self, app): self.versions_app = versions.Controller() super(VersionNegotiationFilter, self).__init__(app) def process_request(self, req): """Try to find a version first in the accept header, then the URL""" msg = _("Determining version of request: %(method)s %(path)s" " Accept: %(accept)s") args = {'method': req.method, 'path': req.path, 'accept': req.accept} LOG.debug(msg % args) # If the request is for /versions, just return the versions container #TODO(bcwaldon): deprecate this behavior if req.path_info_peek() == "versions": return self.versions_app accept = str(req.accept) if accept.startswith('application/vnd.openstack.images-'): LOG.debug(_("Using media-type versioning")) token_loc = len('application/vnd.openstack.images-') req_version = accept[token_loc:] else: LOG.debug(_("Using url versioning")) # Remove version in url so it doesn't conflict later req_version = self._pop_path_info(req) try: version = self._match_version_string(req_version) except ValueError: LOG.debug(_("Unknown version. Returning version choices.")) return self.versions_app req.environ['api.version'] = version req.path_info = ''.join(('/v', str(version), req.path_info)) LOG.debug(_("Matched version: v%d"), version) LOG.debug('new path %s' % req.path_info) return None def _match_version_string(self, subject): """ Given a string, tries to match a major and/or minor version number. :param subject: The string to check :returns version found in the subject :raises ValueError if no acceptable version could be found """ if subject in ('v1', 'v1.0', 'v1.1') and CONF.enable_v1_api: major_version = 1 elif subject in ('v2', 'v2.0', 'v2.1', 'v2.2') and CONF.enable_v2_api: major_version = 2 else: raise ValueError() return major_version def _pop_path_info(self, req): """ 'Pops' off the next segment of PATH_INFO, returns the popped segment. Do NOT push it onto SCRIPT_NAME. """ path = req.path_info if not path: return None while path.startswith('/'): path = path[1:] idx = path.find('/') if idx == -1: idx = len(path) r = path[:idx] req.path_info = path[idx:] return r glance-2014.1/glance/api/middleware/__init__.py0000664000175400017540000000000012323736226022414 0ustar jenkinsjenkins00000000000000glance-2014.1/glance/api/policy.py0000664000175400017540000003536412323736230020057 0ustar jenkinsjenkins00000000000000# Copyright (c) 2011 OpenStack Foundation # Copyright 2013 IBM Corp. # 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. """Policy Engine For Glance""" import copy import os.path from oslo.config import cfg from glance.common import exception import glance.domain.proxy from glance.openstack.common import jsonutils import glance.openstack.common.log as logging from glance.openstack.common import policy LOG = logging.getLogger(__name__) policy_opts = [ cfg.StrOpt('policy_file', default='policy.json', help=_('The location of the policy file.')), cfg.StrOpt('policy_default_rule', default='default', help=_('The default policy to use.')), ] CONF = cfg.CONF CONF.register_opts(policy_opts) DEFAULT_RULES = { 'context_is_admin': policy.RoleCheck('role', 'admin'), 'default': policy.TrueCheck(), 'manage_image_cache': policy.RoleCheck('role', 'admin'), } class Enforcer(object): """Responsible for loading and enforcing rules""" def __init__(self): self.default_rule = CONF.policy_default_rule self.policy_path = self._find_policy_file() self.policy_file_mtime = None self.policy_file_contents = None self.load_rules() def set_rules(self, rules): """Create a new Rules object based on the provided dict of rules""" rules_obj = policy.Rules(rules, self.default_rule) policy.set_rules(rules_obj) def add_rules(self, rules): """Add new rules to the Rules object""" if policy._rules: rules_obj = policy.Rules(rules) policy._rules.update(rules_obj) else: self.set_rules(rules) def load_rules(self): """Set the rules found in the json file on disk""" if self.policy_path: rules = self._read_policy_file() rule_type = "" else: rules = DEFAULT_RULES rule_type = "default " text_rules = dict((k, str(v)) for k, v in rules.items()) msg = (_('Loaded %(rule_type)spolicy rules: %(text_rules)s') % {'rule_type': rule_type, 'text_rules': text_rules}) LOG.debug(msg) self.set_rules(rules) @staticmethod def _find_policy_file(): """Locate the policy json data file""" policy_file = CONF.find_file(CONF.policy_file) if policy_file: return policy_file else: LOG.warn(_('Unable to find policy file')) return None def _read_policy_file(self): """Read contents of the policy file This re-caches policy data if the file has been changed. """ mtime = os.path.getmtime(self.policy_path) if not self.policy_file_contents or mtime != self.policy_file_mtime: LOG.debug(_("Loading policy from %s") % self.policy_path) with open(self.policy_path) as fap: raw_contents = fap.read() rules_dict = jsonutils.loads(raw_contents) self.policy_file_contents = dict( (k, policy.parse_rule(v)) for k, v in rules_dict.items()) self.policy_file_mtime = mtime return self.policy_file_contents def _check(self, context, rule, target, *args, **kwargs): """Verifies that the action is valid on the target in this context. :param context: Glance request context :param rule: String representing the action to be checked :param object: Dictionary representing the object of the action. :raises: `glance.common.exception.Forbidden` :returns: A non-False value if access is allowed. """ credentials = { 'roles': context.roles, 'user': context.user, 'tenant': context.tenant, } return policy.check(rule, target, credentials, *args, **kwargs) def enforce(self, context, action, target): """Verifies that the action is valid on the target in this context. :param context: Glance request context :param action: String representing the action to be checked :param object: Dictionary representing the object of the action. :raises: `glance.common.exception.Forbidden` :returns: A non-False value if access is allowed. """ return self._check(context, action, target, exception.Forbidden, action=action) def check(self, context, action, target): """Verifies that the action is valid on the target in this context. :param context: Glance request context :param action: String representing the action to be checked :param object: Dictionary representing the object of the action. :returns: A non-False value if access is allowed. """ return self._check(context, action, target) def check_is_admin(self, context): """Check if the given context is associated with an admin role, as defined via the 'context_is_admin' RBAC rule. :param context: Glance request context :returns: A non-False value if context role is admin. """ target = context.to_dict() return self.check(context, 'context_is_admin', target) class ImageRepoProxy(glance.domain.proxy.Repo): def __init__(self, image_repo, context, policy): self.context = context self.policy = policy self.image_repo = image_repo proxy_kwargs = {'context': self.context, 'policy': self.policy} super(ImageRepoProxy, self).__init__(image_repo, item_proxy_class=ImageProxy, item_proxy_kwargs=proxy_kwargs) def get(self, image_id): self.policy.enforce(self.context, 'get_image', {}) return super(ImageRepoProxy, self).get(image_id) def list(self, *args, **kwargs): self.policy.enforce(self.context, 'get_images', {}) return super(ImageRepoProxy, self).list(*args, **kwargs) def save(self, image): self.policy.enforce(self.context, 'modify_image', {}) return super(ImageRepoProxy, self).save(image) def add(self, image): self.policy.enforce(self.context, 'add_image', {}) return super(ImageRepoProxy, self).add(image) class ImageProxy(glance.domain.proxy.Image): def __init__(self, image, context, policy): self.image = image self.context = context self.policy = policy super(ImageProxy, self).__init__(image) @property def visibility(self): return self.image.visibility @visibility.setter def visibility(self, value): if value == 'public': self.policy.enforce(self.context, 'publicize_image', {}) self.image.visibility = value @property def locations(self): return ImageLocationsProxy(self.image.locations, self.context, self.policy) @locations.setter def locations(self, value): if not isinstance(value, (list, ImageLocationsProxy)): raise exception.Invalid(_('Invalid locations: %s') % value) self.policy.enforce(self.context, 'set_image_location', {}) new_locations = list(value) if (set([loc['url'] for loc in self.image.locations]) - set([loc['url'] for loc in new_locations])): self.policy.enforce(self.context, 'delete_image_location', {}) self.image.locations = new_locations def delete(self): self.policy.enforce(self.context, 'delete_image', {}) return self.image.delete() def get_data(self, *args, **kwargs): self.policy.enforce(self.context, 'download_image', {}) return self.image.get_data(*args, **kwargs) def set_data(self, *args, **kwargs): self.policy.enforce(self.context, 'upload_image', {}) return self.image.set_data(*args, **kwargs) def get_member_repo(self, **kwargs): member_repo = self.image.get_member_repo(**kwargs) return ImageMemberRepoProxy(member_repo, self.context, self.policy) class ImageFactoryProxy(glance.domain.proxy.ImageFactory): def __init__(self, image_factory, context, policy): self.image_factory = image_factory self.context = context self.policy = policy proxy_kwargs = {'context': self.context, 'policy': self.policy} super(ImageFactoryProxy, self).__init__(image_factory, proxy_class=ImageProxy, proxy_kwargs=proxy_kwargs) def new_image(self, **kwargs): if kwargs.get('visibility') == 'public': self.policy.enforce(self.context, 'publicize_image', {}) return super(ImageFactoryProxy, self).new_image(**kwargs) class ImageMemberFactoryProxy(glance.domain.proxy.ImageMembershipFactory): def __init__(self, member_factory, context, policy): super(ImageMemberFactoryProxy, self).__init__( member_factory, image_proxy_class=ImageProxy, image_proxy_kwargs={'context': context, 'policy': policy}) class ImageMemberRepoProxy(glance.domain.proxy.Repo): def __init__(self, member_repo, context, policy): self.member_repo = member_repo self.context = context self.policy = policy def add(self, member): self.policy.enforce(self.context, 'add_member', {}) self.member_repo.add(member) def get(self, member_id): self.policy.enforce(self.context, 'get_member', {}) return self.member_repo.get(member_id) def save(self, member): self.policy.enforce(self.context, 'modify_member', {}) self.member_repo.save(member) def list(self, *args, **kwargs): self.policy.enforce(self.context, 'get_members', {}) return self.member_repo.list(*args, **kwargs) def remove(self, member): self.policy.enforce(self.context, 'delete_member', {}) self.member_repo.remove(member) class ImageLocationsProxy(object): __hash__ = None def __init__(self, locations, context, policy): self.locations = locations self.context = context self.policy = policy def __copy__(self): return type(self)(self.locations, self.context, self.policy) def __deepcopy__(self, memo): # NOTE(zhiyan): Only copy location entries, others can be reused. return type(self)(copy.deepcopy(self.locations, memo), self.context, self.policy) def _get_checker(action, func_name): def _checker(self, *args, **kwargs): self.policy.enforce(self.context, action, {}) assert hasattr(self.locations, func_name) method = getattr(self.locations, func_name) return method(*args, **kwargs) return _checker count = _get_checker('get_image_location', 'count') index = _get_checker('get_image_location', 'index') __getitem__ = _get_checker('get_image_location', '__getitem__') __contains__ = _get_checker('get_image_location', '__contains__') __len__ = _get_checker('get_image_location', '__len__') __cast = _get_checker('get_image_location', '__cast') __cmp__ = _get_checker('get_image_location', '__cmp__') __iter__ = _get_checker('get_image_location', '__iter__') append = _get_checker('set_image_location', 'append') extend = _get_checker('set_image_location', 'extend') insert = _get_checker('set_image_location', 'insert') reverse = _get_checker('set_image_location', 'reverse') __iadd__ = _get_checker('set_image_location', '__iadd__') __setitem__ = _get_checker('set_image_location', '__setitem__') pop = _get_checker('delete_image_location', 'pop') remove = _get_checker('delete_image_location', 'remove') __delitem__ = _get_checker('delete_image_location', '__delitem__') __delslice__ = _get_checker('delete_image_location', '__delslice__') del _get_checker class TaskProxy(glance.domain.proxy.Task): def __init__(self, task, context, policy): self.task = task self.context = context self.policy = policy super(TaskProxy, self).__init__(task) def run(self, executor): self.base.run(executor) class TaskDetailsProxy(glance.domain.proxy.TaskDetails): def __init__(self, task_details, context, policy): self.task_details = task_details self.context = context self.policy = policy super(TaskDetailsProxy, self).__init__(task_details) class TaskRepoProxy(glance.domain.proxy.TaskRepo): def __init__(self, task_repo, context, task_policy): self.context = context self.policy = task_policy self.task_repo = task_repo proxy_kwargs = {'context': self.context, 'policy': self.policy} super(TaskRepoProxy, self).__init__(task_repo, task_proxy_class=TaskProxy, task_proxy_kwargs=proxy_kwargs, task_details_proxy_class=TaskDetailsProxy, task_details_proxy_kwargs=proxy_kwargs) def get_task_and_details(self, task_id): self.policy.enforce(self.context, 'get_task', {}) return super(TaskRepoProxy, self).get_task_and_details(task_id) def list_tasks(self, *args, **kwargs): self.policy.enforce(self.context, 'get_tasks', {}) return super(TaskRepoProxy, self).list_tasks(*args, **kwargs) def add(self, task, task_details=None): self.policy.enforce(self.context, 'add_task', {}) super(TaskRepoProxy, self).add(task, task_details) def save(self, task, task_details=None): self.policy.enforce(self.context, 'modify_task', {}) super(TaskRepoProxy, self).save(task, task_details) class TaskFactoryProxy(glance.domain.proxy.TaskFactory): def __init__(self, task_factory, context, policy): self.task_factory = task_factory self.context = context self.policy = policy proxy_kwargs = {'context': self.context, 'policy': self.policy} super(TaskFactoryProxy, self).__init__( task_factory, task_proxy_class=TaskProxy, task_proxy_kwargs=proxy_kwargs, task_details_proxy_class=TaskDetailsProxy, task_details_proxy_kwargs=proxy_kwargs) glance-2014.1/glance/api/versions.py0000664000175400017540000000437212323736226020430 0ustar jenkinsjenkins00000000000000# Copyright 2012 OpenStack Foundation. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import httplib from oslo.config import cfg import webob.dec from glance.common import wsgi from glance.openstack.common import jsonutils CONF = cfg.CONF class Controller(object): """A wsgi controller that reports which API versions are supported.""" def index(self, req): """Respond to a request for all OpenStack API versions.""" def build_version_object(version, path, status): return { 'id': 'v%s' % version, 'status': status, 'links': [ { 'rel': 'self', 'href': '%s/%s/' % (req.host_url, path), }, ], } version_objs = [] if CONF.enable_v2_api: version_objs.extend([ build_version_object(2.2, 'v2', 'CURRENT'), build_version_object(2.1, 'v2', 'SUPPORTED'), build_version_object(2.0, 'v2', 'SUPPORTED'), ]) if CONF.enable_v1_api: version_objs.extend([ build_version_object(1.1, 'v1', 'CURRENT'), build_version_object(1.0, 'v1', 'SUPPORTED'), ]) response = webob.Response(request=req, status=httplib.MULTIPLE_CHOICES, content_type='application/json') response.body = jsonutils.dumps(dict(versions=version_objs)) return response @webob.dec.wsgify(RequestClass=wsgi.Request) def __call__(self, req): return self.index(req) def create_resource(conf): return wsgi.Resource(Controller()) glance-2014.1/glance/api/common.py0000664000175400017540000001315012323736230020035 0ustar jenkinsjenkins00000000000000# Copyright 2012 OpenStack Foundation. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from oslo.config import cfg from glance.common import exception from glance.openstack.common import log as logging LOG = logging.getLogger(__name__) CONF = cfg.CONF def size_checked_iter(response, image_meta, expected_size, image_iter, notifier): image_id = image_meta['id'] bytes_written = 0 def notify_image_sent_hook(env): image_send_notification(bytes_written, expected_size, image_meta, response.request, notifier) # Add hook to process after response is fully sent if 'eventlet.posthooks' in response.request.environ: response.request.environ['eventlet.posthooks'].append( (notify_image_sent_hook, (), {})) try: for chunk in image_iter: yield chunk bytes_written += len(chunk) except Exception as err: msg = (_("An error occurred reading from backend storage " "for image %(image_id)s: %(err)s") % {'image_id': image_id, 'err': err}) LOG.error(msg) raise if expected_size != bytes_written: msg = (_("Backend storage for image %(image_id)s " "disconnected after writing only %(bytes_written)d " "bytes") % {'image_id': image_id, 'bytes_written': bytes_written}) LOG.error(msg) raise exception.GlanceException(_("Corrupt image download for " "image %(image_id)s") % {'image_id': image_id}) def image_send_notification(bytes_written, expected_size, image_meta, request, notifier): """Send an image.send message to the notifier.""" try: context = request.context payload = { 'bytes_sent': bytes_written, 'image_id': image_meta['id'], 'owner_id': image_meta['owner'], 'receiver_tenant_id': context.tenant, 'receiver_user_id': context.user, 'destination_ip': request.remote_addr, } if bytes_written != expected_size: notify = notifier.error else: notify = notifier.info notify('image.send', payload) except Exception as err: msg = (_("An error occurred during image.send" " notification: %(err)s") % {'err': err}) LOG.error(msg) def get_remaining_quota(context, db_api, image_id=None): """ This method is called to see if the user is allowed to store an image of the given size in glance based on their quota and current usage. :param context: :param db_api: The db_api in use for this configuration :param image_id: The image that will be replaced with this new data size :return: The number of bytes the user has remaining under their quota. None means infinity """ #NOTE(jbresnah) in the future this value will come from a call to # keystone. users_quota = CONF.user_storage_quota if users_quota <= 0: return None usage = db_api.user_get_storage_usage(context, context.owner, image_id=image_id) return users_quota - usage def check_quota(context, image_size, db_api, image_id=None): """ This method is called to see if the user is allowed to store an image of the given size in glance based on their quota and current usage. :param context: :param image_size: The size of the image we hope to store :param db_api: The db_api in use for this configuration :param image_id: The image that will be replaced with this new data size :return: """ remaining = get_remaining_quota(context, db_api, image_id=image_id) if remaining is None: return user = getattr(context, 'user', '') if image_size is None: #NOTE(jbresnah) When the image size is None it means that it is # not known. In this case the only time we will raise an # exception is when there is no room left at all, thus we know # it will not fit if remaining <= 0: LOG.info(_("User %(user)s attempted to upload an image of" " unknown size that will exceeed the quota." " %(remaining)d bytes remaining.") % {'user': user, 'remaining': remaining}) raise exception.StorageQuotaFull(image_size=image_size, remaining=remaining) return if image_size > remaining: LOG.info(_("User %(user)s attempted to upload an image of size" " %(size)d that will exceeed the quota. %(remaining)d" " bytes remaining.") % {'user': user, 'size': image_size, 'remaining': remaining}) raise exception.StorageQuotaFull(image_size=image_size, remaining=remaining) return remaining glance-2014.1/glance/api/v2/0000775000175400017540000000000012323736427016532 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/api/v2/schemas.py0000664000175400017540000000352412323736226020530 0ustar jenkinsjenkins00000000000000# Copyright 2012 OpenStack Foundation. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from glance.api.v2 import image_members from glance.api.v2 import images from glance.api.v2 import tasks from glance.common import wsgi class Controller(object): def __init__(self, custom_image_properties=None): self.image_schema = images.get_schema(custom_image_properties) self.image_collection_schema = images.get_collection_schema( custom_image_properties) self.member_schema = image_members.get_schema() self.member_collection_schema = image_members.get_collection_schema() self.task_schema = tasks.get_task_schema() self.task_collection_schema = tasks.get_collection_schema() def image(self, req): return self.image_schema.raw() def images(self, req): return self.image_collection_schema.raw() def member(self, req): return self.member_schema.minimal() def members(self, req): return self.member_collection_schema.minimal() def task(self, req): return self.task_schema.minimal() def tasks(self, req): return self.task_collection_schema.minimal() def create_resource(custom_image_properties=None): controller = Controller(custom_image_properties) return wsgi.Resource(controller) glance-2014.1/glance/api/v2/image_tags.py0000664000175400017540000000553612323736226021212 0ustar jenkinsjenkins00000000000000# Copyright 2012 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import webob.exc from glance.api import policy from glance.common import exception from glance.common import utils from glance.common import wsgi import glance.db import glance.gateway import glance.notifier import glance.store class Controller(object): def __init__(self, db_api=None, policy_enforcer=None, notifier=None, store_api=None): self.db_api = db_api or glance.db.get_api() self.policy = policy_enforcer or policy.Enforcer() self.notifier = notifier or glance.notifier.Notifier() self.store_api = store_api or glance.store self.gateway = glance.gateway.Gateway(self.db_api, self.store_api, self.notifier, self.policy) @utils.mutating def update(self, req, image_id, tag_value): image_repo = self.gateway.get_repo(req.context) try: image = image_repo.get(image_id) image.tags.add(tag_value) image_repo.save(image) except exception.NotFound as e: raise webob.exc.HTTPNotFound(explanation=e.msg) except exception.Forbidden as e: raise webob.exc.HTTPForbidden(explanation=e.msg) except exception.ImageTagLimitExceeded as e: raise webob.exc.HTTPRequestEntityTooLarge(explanation=e.msg) @utils.mutating def delete(self, req, image_id, tag_value): image_repo = self.gateway.get_repo(req.context) try: image = image_repo.get(image_id) if tag_value not in image.tags: raise webob.exc.HTTPNotFound() image.tags.remove(tag_value) image_repo.save(image) except exception.NotFound as e: raise webob.exc.HTTPNotFound(explanation=e.msg) except exception.Forbidden as e: raise webob.exc.HTTPForbidden(explanation=e.msg) class ResponseSerializer(wsgi.JSONResponseSerializer): def update(self, response, result): response.status_int = 204 def delete(self, response, result): response.status_int = 204 def create_resource(): """Images resource factory method""" serializer = ResponseSerializer() controller = Controller() return wsgi.Resource(controller, serializer=serializer) glance-2014.1/glance/api/v2/images.py0000664000175400017540000007620612323736226020361 0ustar jenkinsjenkins00000000000000# Copyright 2012 OpenStack Foundation. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import re from oslo.config import cfg import six.moves.urllib.parse as urlparse import webob.exc from glance.api import policy from glance.common import exception from glance.common import location_strategy from glance.common import utils from glance.common import wsgi import glance.db import glance.gateway import glance.notifier from glance.openstack.common import jsonutils as json import glance.openstack.common.log as logging from glance.openstack.common import timeutils import glance.schema import glance.store LOG = logging.getLogger(__name__) CONF = cfg.CONF CONF.import_opt('disk_formats', 'glance.common.config', group='image_format') CONF.import_opt('container_formats', 'glance.common.config', group='image_format') class ImagesController(object): def __init__(self, db_api=None, policy_enforcer=None, notifier=None, store_api=None): self.db_api = db_api or glance.db.get_api() self.policy = policy_enforcer or policy.Enforcer() self.notifier = notifier or glance.notifier.Notifier() self.store_api = store_api or glance.store self.gateway = glance.gateway.Gateway(self.db_api, self.store_api, self.notifier, self.policy) @utils.mutating def create(self, req, image, extra_properties, tags): image_factory = self.gateway.get_image_factory(req.context) image_repo = self.gateway.get_repo(req.context) try: image = image_factory.new_image(extra_properties=extra_properties, tags=tags, **image) image_repo.add(image) except exception.DuplicateLocation as dup: raise webob.exc.HTTPBadRequest(explanation=dup.msg) except exception.Forbidden as e: raise webob.exc.HTTPForbidden(explanation=e.msg) except exception.InvalidParameterValue as e: raise webob.exc.HTTPBadRequest(explanation=e.msg) except exception.LimitExceeded as e: LOG.info(unicode(e)) raise webob.exc.HTTPRequestEntityTooLarge( explanation=e.msg, request=req, content_type='text/plain') return image def index(self, req, marker=None, limit=None, sort_key='created_at', sort_dir='desc', filters=None, member_status='accepted'): result = {} if filters is None: filters = {} filters['deleted'] = False if limit is None: limit = CONF.limit_param_default limit = min(CONF.api_limit_max, limit) image_repo = self.gateway.get_repo(req.context) try: images = image_repo.list(marker=marker, limit=limit, sort_key=sort_key, sort_dir=sort_dir, filters=filters, member_status=member_status) if len(images) != 0 and len(images) == limit: result['next_marker'] = images[-1].image_id except (exception.NotFound, exception.InvalidSortKey, exception.InvalidFilterRangeValue) as e: raise webob.exc.HTTPBadRequest(explanation=e.msg) except exception.Forbidden as e: raise webob.exc.HTTPForbidden(explanation=e.msg) result['images'] = images return result def show(self, req, image_id): image_repo = self.gateway.get_repo(req.context) try: return image_repo.get(image_id) except exception.Forbidden as e: raise webob.exc.HTTPForbidden(explanation=e.msg) except exception.NotFound as e: raise webob.exc.HTTPNotFound(explanation=e.msg) @utils.mutating def update(self, req, image_id, changes): image_repo = self.gateway.get_repo(req.context) try: image = image_repo.get(image_id) for change in changes: change_method_name = '_do_%s' % change['op'] assert hasattr(self, change_method_name) change_method = getattr(self, change_method_name) change_method(req, image, change) if changes: image_repo.save(image) except exception.NotFound as e: raise webob.exc.HTTPNotFound(explanation=e.msg) except exception.Forbidden as e: raise webob.exc.HTTPForbidden(explanation=e.msg) except exception.InvalidParameterValue as e: raise webob.exc.HTTPBadRequest(explanation=e.msg) except exception.StorageQuotaFull as e: msg = (_("Denying attempt to upload image because it exceeds the ." "quota: %s") % e) LOG.info(msg) raise webob.exc.HTTPRequestEntityTooLarge( explanation=msg, request=req, content_type='text/plain') except exception.LimitExceeded as e: LOG.info(unicode(e)) raise webob.exc.HTTPRequestEntityTooLarge( explanation=e.msg, request=req, content_type='text/plain') return image def _do_replace(self, req, image, change): path = change['path'] path_root = path[0] value = change['value'] if path_root == 'locations': self._do_replace_locations(image, value) else: if hasattr(image, path_root): setattr(image, path_root, value) elif path_root in image.extra_properties: image.extra_properties[path_root] = value else: msg = _("Property %s does not exist.") raise webob.exc.HTTPConflict(msg % path_root) def _do_add(self, req, image, change): path = change['path'] path_root = path[0] value = change['value'] if path_root == 'locations': self._do_add_locations(image, path[1], value) else: if (hasattr(image, path_root) or path_root in image.extra_properties): msg = _("Property %s already present.") raise webob.exc.HTTPConflict(msg % path_root) image.extra_properties[path_root] = value def _do_remove(self, req, image, change): path = change['path'] path_root = path[0] if path_root == 'locations': self._do_remove_locations(image, path[1]) else: if hasattr(image, path_root): msg = _("Property %s may not be removed.") raise webob.exc.HTTPForbidden(msg % path_root) elif path_root in image.extra_properties: del image.extra_properties[path_root] else: msg = _("Property %s does not exist.") raise webob.exc.HTTPConflict(msg % path_root) @utils.mutating def delete(self, req, image_id): image_repo = self.gateway.get_repo(req.context) try: image = image_repo.get(image_id) image.delete() image_repo.remove(image) except exception.Forbidden as e: raise webob.exc.HTTPForbidden(explanation=e.msg) except exception.NotFound as e: msg = (_("Failed to find image %(image_id)s to delete") % {'image_id': image_id}) LOG.info(msg) raise webob.exc.HTTPNotFound(explanation=msg) def _get_locations_op_pos(self, path_pos, max_pos, allow_max): if path_pos is None or max_pos is None: return None pos = max_pos if allow_max else max_pos - 1 if path_pos.isdigit(): pos = int(path_pos) elif path_pos != '-': return None if (not allow_max) and (pos not in range(max_pos)): return None return pos def _do_replace_locations(self, image, value): if len(image.locations) > 0 and len(value) > 0: msg = _("Cannot replace locations from a non-empty " "list to a non-empty list.") raise webob.exc.HTTPBadRequest(explanation=msg) if len(value) == 0: # NOTE(zhiyan): this actually deletes the location # from the backend store. del image.locations[:] if image.status == 'active': image.status = 'queued' else: # NOTE(zhiyan): len(image.locations) == 0 try: image.locations = value if image.status == 'queued': image.status = 'active' except (exception.BadStoreUri, exception.DuplicateLocation) as bse: raise webob.exc.HTTPBadRequest(explanation=bse.msg) except ValueError as ve: # update image status failed. raise webob.exc.HTTPBadRequest(explanation=unicode(ve)) def _do_add_locations(self, image, path_pos, value): pos = self._get_locations_op_pos(path_pos, len(image.locations), True) if pos is None: msg = _("Invalid position for adding a location.") raise webob.exc.HTTPBadRequest(explanation=msg) try: image.locations.insert(pos, value) if image.status == 'queued': image.status = 'active' except (exception.BadStoreUri, exception.DuplicateLocation) as bse: raise webob.exc.HTTPBadRequest(explanation=bse.msg) except ValueError as ve: # update image status failed. raise webob.exc.HTTPBadRequest(explanation=unicode(ve)) def _do_remove_locations(self, image, path_pos): pos = self._get_locations_op_pos(path_pos, len(image.locations), False) if pos is None: msg = _("Invalid position for removing a location.") raise webob.exc.HTTPBadRequest(explanation=msg) try: # NOTE(zhiyan): this actually deletes the location # from the backend store. image.locations.pop(pos) except Exception as e: raise webob.exc.HTTPInternalServerError(explanation=unicode(e)) if (len(image.locations) == 0) and (image.status == 'active'): image.status = 'queued' class RequestDeserializer(wsgi.JSONRequestDeserializer): _disallowed_properties = ['direct_url', 'self', 'file', 'schema'] _readonly_properties = ['created_at', 'updated_at', 'status', 'checksum', 'size', 'virtual_size', 'direct_url', 'self', 'file', 'schema'] _reserved_properties = ['owner', 'is_public', 'location', 'deleted', 'deleted_at'] _base_properties = ['checksum', 'created_at', 'container_format', 'disk_format', 'id', 'min_disk', 'min_ram', 'name', 'size', 'virtual_size', 'status', 'tags', 'updated_at', 'visibility', 'protected'] _path_depth_limits = {'locations': {'add': 2, 'remove': 2, 'replace': 1}} def __init__(self, schema=None): super(RequestDeserializer, self).__init__() self.schema = schema or get_schema() def _get_request_body(self, request): output = super(RequestDeserializer, self).default(request) if 'body' not in output: msg = _('Body expected in request.') raise webob.exc.HTTPBadRequest(explanation=msg) return output['body'] @classmethod def _check_allowed(cls, image): for key in cls._disallowed_properties: if key in image: msg = _("Attribute '%s' is read-only.") % key raise webob.exc.HTTPForbidden(explanation=unicode(msg)) def create(self, request): body = self._get_request_body(request) self._check_allowed(body) try: self.schema.validate(body) except exception.InvalidObject as e: raise webob.exc.HTTPBadRequest(explanation=e.msg) image = {} properties = body tags = properties.pop('tags', None) for key in self._base_properties: try: image[key] = properties.pop(key) except KeyError: pass return dict(image=image, extra_properties=properties, tags=tags) def _get_change_operation_d10(self, raw_change): try: return raw_change['op'] except KeyError: msg = _("Unable to find '%s' in JSON Schema change") % 'op' raise webob.exc.HTTPBadRequest(explanation=msg) def _get_change_operation_d4(self, raw_change): op = None for key in ['replace', 'add', 'remove']: if key in raw_change: if op is not None: msg = _('Operation objects must contain only one member' ' named "add", "remove", or "replace".') raise webob.exc.HTTPBadRequest(explanation=msg) op = key if op is None: msg = _('Operation objects must contain exactly one member' ' named "add", "remove", or "replace".') raise webob.exc.HTTPBadRequest(explanation=msg) return op def _get_change_path_d10(self, raw_change): try: return raw_change['path'] except KeyError: msg = _("Unable to find '%s' in JSON Schema change") % 'path' raise webob.exc.HTTPBadRequest(explanation=msg) def _get_change_path_d4(self, raw_change, op): return raw_change[op] def _decode_json_pointer(self, pointer): """Parse a json pointer. Json Pointers are defined in http://tools.ietf.org/html/draft-pbryan-zyp-json-pointer . The pointers use '/' for separation between object attributes, such that '/A/B' would evaluate to C in {"A": {"B": "C"}}. A '/' character in an attribute name is encoded as "~1" and a '~' character is encoded as "~0". """ self._validate_json_pointer(pointer) ret = [] for part in pointer.lstrip('/').split('/'): ret.append(part.replace('~1', '/').replace('~0', '~').strip()) return ret def _validate_json_pointer(self, pointer): """Validate a json pointer. We only accept a limited form of json pointers. """ if not pointer.startswith('/'): msg = _('Pointer `%s` does not start with "/".') % pointer raise webob.exc.HTTPBadRequest(explanation=msg) if re.search('/\s*?/', pointer[1:]): msg = _('Pointer `%s` contains adjacent "/".') % pointer raise webob.exc.HTTPBadRequest(explanation=msg) if len(pointer) > 1 and pointer.endswith('/'): msg = _('Pointer `%s` end with "/".') % pointer raise webob.exc.HTTPBadRequest(explanation=msg) if pointer[1:].strip() == '/': msg = _('Pointer `%s` does not contains valid token.') % pointer raise webob.exc.HTTPBadRequest(explanation=msg) if re.search('~[^01]', pointer) or pointer.endswith('~'): msg = _('Pointer `%s` contains "~" not part of' ' a recognized escape sequence.') % pointer raise webob.exc.HTTPBadRequest(explanation=msg) def _get_change_value(self, raw_change, op): if 'value' not in raw_change: msg = _('Operation "%s" requires a member named "value".') raise webob.exc.HTTPBadRequest(explanation=msg % op) return raw_change['value'] def _validate_change(self, change): path_root = change['path'][0] if path_root in self._readonly_properties: msg = _("Attribute '%s' is read-only.") % path_root raise webob.exc.HTTPForbidden(explanation=unicode(msg)) if path_root in self._reserved_properties: msg = _("Attribute '%s' is reserved.") % path_root raise webob.exc.HTTPForbidden(explanation=unicode(msg)) if change['op'] == 'delete': return partial_image = None if len(change['path']) == 1: partial_image = {path_root: change['value']} elif ((path_root in _get_base_properties().keys()) and (_get_base_properties()[path_root].get('type', '') == 'array')): # NOTE(zhiyan): cient can use PATCH API to adding element to # the image's existing set property directly. # Such as: 1. using '/locations/N' path to adding a location # to the image's 'locations' list at N position. # (implemented) # 2. using '/tags/-' path to appending a tag to the # image's 'tags' list at last. (Not implemented) partial_image = {path_root: [change['value']]} if partial_image: try: self.schema.validate(partial_image) except exception.InvalidObject as e: raise webob.exc.HTTPBadRequest(explanation=e.msg) def _validate_path(self, op, path): path_root = path[0] limits = self._path_depth_limits.get(path_root, {}) if len(path) != limits.get(op, 1): msg = _("Invalid JSON pointer for this resource: " "'/%s'") % '/'.join(path) raise webob.exc.HTTPBadRequest(explanation=unicode(msg)) def _parse_json_schema_change(self, raw_change, draft_version): if draft_version == 10: op = self._get_change_operation_d10(raw_change) path = self._get_change_path_d10(raw_change) elif draft_version == 4: op = self._get_change_operation_d4(raw_change) path = self._get_change_path_d4(raw_change, op) else: msg = _('Unrecognized JSON Schema draft version') raise webob.exc.HTTPBadRequest(explanation=msg) path_list = self._decode_json_pointer(path) return op, path_list def update(self, request): changes = [] content_types = { 'application/openstack-images-v2.0-json-patch': 4, 'application/openstack-images-v2.1-json-patch': 10, } if request.content_type not in content_types: headers = {'Accept-Patch': ', '.join(content_types.keys())} raise webob.exc.HTTPUnsupportedMediaType(headers=headers) json_schema_version = content_types[request.content_type] body = self._get_request_body(request) if not isinstance(body, list): msg = _('Request body must be a JSON array of operation objects.') raise webob.exc.HTTPBadRequest(explanation=msg) for raw_change in body: if not isinstance(raw_change, dict): msg = _('Operations must be JSON objects.') raise webob.exc.HTTPBadRequest(explanation=msg) (op, path) = self._parse_json_schema_change(raw_change, json_schema_version) # NOTE(zhiyan): the 'path' is a list. self._validate_path(op, path) change = {'op': op, 'path': path} if not op == 'remove': change['value'] = self._get_change_value(raw_change, op) self._validate_change(change) changes.append(change) return {'changes': changes} def _validate_limit(self, limit): try: limit = int(limit) except ValueError: msg = _("limit param must be an integer") raise webob.exc.HTTPBadRequest(explanation=msg) if limit < 0: msg = _("limit param must be positive") raise webob.exc.HTTPBadRequest(explanation=msg) return limit def _validate_sort_dir(self, sort_dir): if sort_dir not in ['asc', 'desc']: msg = _('Invalid sort direction: %s') % sort_dir raise webob.exc.HTTPBadRequest(explanation=msg) return sort_dir def _validate_member_status(self, member_status): if member_status not in ['pending', 'accepted', 'rejected', 'all']: msg = _('Invalid status: %s') % member_status raise webob.exc.HTTPBadRequest(explanation=msg) return member_status def _get_filters(self, filters): visibility = filters.get('visibility') if visibility: if visibility not in ['public', 'private', 'shared']: msg = _('Invalid visibility value: %s') % visibility raise webob.exc.HTTPBadRequest(explanation=msg) return filters def index(self, request): params = request.params.copy() limit = params.pop('limit', None) marker = params.pop('marker', None) sort_dir = params.pop('sort_dir', 'desc') member_status = params.pop('member_status', 'accepted') # NOTE (flwang) To avoid using comma or any predefined chars to split # multiple tags, now we allow user specify multiple 'tag' parameters # in URL, such as v2/images?tag=x86&tag=64bit. tags = [] while 'tag' in params: tags.append(params.pop('tag').strip()) query_params = { 'sort_key': params.pop('sort_key', 'created_at'), 'sort_dir': self._validate_sort_dir(sort_dir), 'filters': self._get_filters(params), 'member_status': self._validate_member_status(member_status), } if marker is not None: query_params['marker'] = marker if limit is not None: query_params['limit'] = self._validate_limit(limit) if tags: query_params['filters']['tags'] = tags return query_params class ResponseSerializer(wsgi.JSONResponseSerializer): def __init__(self, schema=None): super(ResponseSerializer, self).__init__() self.schema = schema or get_schema() def _get_image_href(self, image, subcollection=''): base_href = '/v2/images/%s' % image.image_id if subcollection: base_href = '%s/%s' % (base_href, subcollection) return base_href def _format_image(self, image): image_view = dict() try: image_view = dict(image.extra_properties) attributes = ['name', 'disk_format', 'container_format', 'visibility', 'size', 'virtual_size', 'status', 'checksum', 'protected', 'min_ram', 'min_disk', 'owner'] for key in attributes: image_view[key] = getattr(image, key) image_view['id'] = image.image_id image_view['created_at'] = timeutils.isotime(image.created_at) image_view['updated_at'] = timeutils.isotime(image.updated_at) if CONF.show_multiple_locations: if image.locations: image_view['locations'] = list(image.locations) else: # NOTE (flwang): We will still show "locations": [] if # image.locations is None to indicate it's allowed to show # locations but it's just non-existent. image_view['locations'] = [] if CONF.show_image_direct_url and image.locations: # Choose best location configured strategy best_location = ( location_strategy.choose_best_location(image.locations)) image_view['direct_url'] = best_location['url'] image_view['tags'] = list(image.tags) image_view['self'] = self._get_image_href(image) image_view['file'] = self._get_image_href(image, 'file') image_view['schema'] = '/v2/schemas/image' image_view = self.schema.filter(image_view) # domain except exception.Forbidden as e: raise webob.exc.HTTPForbidden(explanation=e.msg) return image_view def create(self, response, image): response.status_int = 201 self.show(response, image) response.location = self._get_image_href(image) def show(self, response, image): image_view = self._format_image(image) body = json.dumps(image_view, ensure_ascii=False) response.unicode_body = unicode(body) response.content_type = 'application/json' def update(self, response, image): image_view = self._format_image(image) body = json.dumps(image_view, ensure_ascii=False) response.unicode_body = unicode(body) response.content_type = 'application/json' def index(self, response, result): params = dict(response.request.params) params.pop('marker', None) query = urlparse.urlencode(params) body = { 'images': [self._format_image(i) for i in result['images']], 'first': '/v2/images', 'schema': '/v2/schemas/images', } if query: body['first'] = '%s?%s' % (body['first'], query) if 'next_marker' in result: params['marker'] = result['next_marker'] next_query = urlparse.urlencode(params) body['next'] = '/v2/images?%s' % next_query response.unicode_body = unicode(json.dumps(body, ensure_ascii=False)) response.content_type = 'application/json' def delete(self, response, result): response.status_int = 204 def _get_base_properties(): return { 'id': { 'type': 'string', 'description': _('An identifier for the image'), 'pattern': ('^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}' '-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}$'), }, 'name': { 'type': 'string', 'description': _('Descriptive name for the image'), 'maxLength': 255, }, 'status': { 'type': 'string', 'description': _('Status of the image (READ-ONLY)'), 'enum': ['queued', 'saving', 'active', 'killed', 'deleted', 'pending_delete'], }, 'visibility': { 'type': 'string', 'description': _('Scope of image accessibility'), 'enum': ['public', 'private'], }, 'protected': { 'type': 'boolean', 'description': _('If true, image will not be deletable.'), }, 'checksum': { 'type': 'string', 'description': _('md5 hash of image contents. (READ-ONLY)'), 'maxLength': 32, }, 'owner': { 'type': 'string', 'description': _('Owner of the image'), 'maxLength': 255, }, 'size': { 'type': 'integer', 'description': _('Size of image file in bytes (READ-ONLY)'), }, 'virtual_size': { 'type': 'integer', 'description': _('Virtual size of image in bytes (READ-ONLY)'), }, 'container_format': { 'type': 'string', 'description': _('Format of the container'), 'enum': CONF.image_format.container_formats, }, 'disk_format': { 'type': 'string', 'description': _('Format of the disk'), 'enum': CONF.image_format.disk_formats, }, 'created_at': { 'type': 'string', 'description': _('Date and time of image registration' ' (READ-ONLY)'), #TODO(bcwaldon): our jsonschema library doesn't seem to like the # format attribute, figure out why! #'format': 'date-time', }, 'updated_at': { 'type': 'string', 'description': _('Date and time of the last image modification' ' (READ-ONLY)'), #'format': 'date-time', }, 'tags': { 'type': 'array', 'description': _('List of strings related to the image'), 'items': { 'type': 'string', 'maxLength': 255, }, }, 'direct_url': { 'type': 'string', 'description': _('URL to access the image file kept in external ' 'store (READ-ONLY)'), }, 'min_ram': { 'type': 'integer', 'description': _('Amount of ram (in MB) required to boot image.'), }, 'min_disk': { 'type': 'integer', 'description': _('Amount of disk space (in GB) required to boot ' 'image.'), }, 'self': { 'type': 'string', 'description': '(READ-ONLY)' }, 'file': { 'type': 'string', 'description': '(READ-ONLY)' }, 'schema': { 'type': 'string', 'description': '(READ-ONLY)' }, 'locations': { 'type': 'array', 'items': { 'type': 'object', 'properties': { 'url': { 'type': 'string', 'maxLength': 255, }, 'metadata': { 'type': 'object', }, }, 'required': ['url', 'metadata'], }, 'description': _('A set of URLs to access the image file kept in ' 'external store'), }, } def _get_base_links(): return [ {'rel': 'self', 'href': '{self}'}, {'rel': 'enclosure', 'href': '{file}'}, {'rel': 'describedby', 'href': '{schema}'}, ] def get_schema(custom_properties=None): properties = _get_base_properties() links = _get_base_links() if CONF.allow_additional_image_properties: schema = glance.schema.PermissiveSchema('image', properties, links) else: schema = glance.schema.Schema('image', properties) schema.merge_properties(custom_properties or {}) return schema def get_collection_schema(custom_properties=None): image_schema = get_schema(custom_properties) return glance.schema.CollectionSchema('images', image_schema) def load_custom_properties(): """Find the schema properties files and load them into a dict.""" filename = 'schema-image.json' match = CONF.find_file(filename) if match: schema_file = open(match) schema_data = schema_file.read() return json.loads(schema_data) else: msg = _('Could not find schema properties file %s. Continuing ' 'without custom properties') LOG.warn(msg % filename) return {} def create_resource(custom_properties=None): """Images resource factory method""" schema = get_schema(custom_properties) deserializer = RequestDeserializer(schema) serializer = ResponseSerializer(schema) controller = ImagesController() return wsgi.Resource(controller, deserializer, serializer) glance-2014.1/glance/api/v2/tasks.py0000664000175400017540000003342012323736230020223 0ustar jenkinsjenkins00000000000000# Copyright 2013 IBM Corp. # 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 copy import webob.exc from oslo.config import cfg import six.moves.urllib.parse as urlparse from glance.api import policy from glance.common import exception from glance.common import utils from glance.common import wsgi import glance.db import glance.gateway import glance.notifier import glance.openstack.common.jsonutils as json import glance.openstack.common.log as logging from glance.openstack.common import timeutils import glance.schema import glance.store LOG = logging.getLogger(__name__) CONF = cfg.CONF CONF.import_opt('task_time_to_live', 'glance.common.config', group='task') class TasksController(object): """Manages operations on tasks.""" def __init__(self, db_api=None, policy_enforcer=None, notifier=None, store_api=None): self.db_api = db_api or glance.db.get_api() self.policy = policy_enforcer or policy.Enforcer() self.notifier = notifier or glance.notifier.Notifier() self.store_api = store_api or glance.store self.gateway = glance.gateway.Gateway(self.db_api, self.store_api, self.notifier, self.policy) def create(self, req, task): task_factory = self.gateway.get_task_factory(req.context) task_repo = self.gateway.get_task_repo(req.context) live_time = CONF.task.task_time_to_live try: new_task = task_factory.new_task(task_type=task['type'], owner=req.context.owner, task_time_to_live=live_time) new_task_details = task_factory.new_task_details(new_task.task_id, task['input']) task_repo.add(new_task, new_task_details) except exception.Forbidden as e: msg = (_("Forbidden to create task. Reason: %(reason)s") % {'reason': unicode(e)}) LOG.info(msg) raise webob.exc.HTTPForbidden(explanation=e.msg) result = {'task': new_task, 'task_details': new_task_details} return result def index(self, req, marker=None, limit=None, sort_key='created_at', sort_dir='desc', filters=None): result = {} if filters is None: filters = {} filters['deleted'] = False if limit is None: limit = CONF.limit_param_default limit = min(CONF.api_limit_max, limit) task_repo = self.gateway.get_task_repo(req.context) try: tasks = task_repo.list_tasks(marker, limit, sort_key, sort_dir, filters) if len(tasks) != 0 and len(tasks) == limit: result['next_marker'] = tasks[-1].task_id except (exception.NotFound, exception.InvalidSortKey, exception.InvalidFilterRangeValue) as e: LOG.info(unicode(e)) raise webob.exc.HTTPBadRequest(explanation=e.msg) except exception.Forbidden as e: LOG.info(unicode(e)) raise webob.exc.HTTPForbidden(explanation=e.msg) result['tasks'] = tasks return result def get(self, req, task_id): try: task_repo = self.gateway.get_task_repo(req.context) task, task_details = task_repo.get_task_and_details(task_id) except exception.NotFound as e: msg = (_("Failed to find task %(task_id)s. Reason: %(reason)s") % {'task_id': task_id, 'reason': unicode(e)}) LOG.info(msg) raise webob.exc.HTTPNotFound(explanation=e.msg) except exception.Forbidden as e: msg = (_("Forbidden to get task %(task_id)s. Reason: %(reason)s") % {'task_id': task_id, 'reason': unicode(e)}) LOG.info(msg) raise webob.exc.HTTPForbidden(explanation=e.msg) result = {'task': task, 'task_details': task_details} return result def delete(self, req, task_id): msg = (_("This operation is currently not permitted on Glance Tasks. " "They are auto deleted after reaching the time based on " "their expires_at property.")) raise webob.exc.HTTPMethodNotAllowed(explanation=msg, headers={'Allow': 'GET'}, body_template='${explanation}') class RequestDeserializer(wsgi.JSONRequestDeserializer): _required_properties = ['type', 'input'] def _get_request_body(self, request): output = super(RequestDeserializer, self).default(request) if 'body' not in output: msg = _('Body expected in request') raise webob.exc.HTTPBadRequest(explanation=msg) return output['body'] def _validate_sort_dir(self, sort_dir): if sort_dir not in ['asc', 'desc']: msg = _('Invalid sort direction: %s') % sort_dir raise webob.exc.HTTPBadRequest(explanation=msg) return sort_dir def _get_filters(self, filters): status = filters.get('status') if status: if status not in ['pending', 'processing', 'success', 'failure']: msg = _('Invalid status value: %s') % status raise webob.exc.HTTPBadRequest(explanation=msg) type = filters.get('type') if type: if type not in ['import']: msg = _('Invalid type value: %s') % type raise webob.exc.HTTPBadRequest(explanation=msg) return filters def _validate_marker(self, marker): if marker and not utils.is_uuid_like(marker): msg = _('Invalid marker format') raise webob.exc.HTTPBadRequest(explanation=msg) return marker def _validate_limit(self, limit): try: limit = int(limit) except ValueError: msg = _("limit param must be an integer") raise webob.exc.HTTPBadRequest(explanation=msg) if limit < 0: msg = _("limit param must be positive") raise webob.exc.HTTPBadRequest(explanation=msg) return limit def _validate_create_body(self, body): """Validate the body of task creating request""" for param in self._required_properties: if param not in body: msg = _("Task '%s' is required") % param raise webob.exc.HTTPBadRequest(explanation=unicode(msg)) def __init__(self, schema=None): super(RequestDeserializer, self).__init__() self.schema = schema or get_task_schema() def create(self, request): body = self._get_request_body(request) self._validate_create_body(body) try: self.schema.validate(body) except exception.InvalidObject as e: raise webob.exc.HTTPBadRequest(explanation=e.msg) task = {} properties = body for key in self._required_properties: try: task[key] = properties.pop(key) except KeyError: pass return dict(task=task) def index(self, request): params = request.params.copy() limit = params.pop('limit', None) marker = params.pop('marker', None) sort_dir = params.pop('sort_dir', 'desc') query_params = { 'sort_key': params.pop('sort_key', 'created_at'), 'sort_dir': self._validate_sort_dir(sort_dir), 'filters': self._get_filters(params) } if marker is not None: query_params['marker'] = self._validate_marker(marker) if limit is not None: query_params['limit'] = self._validate_limit(limit) return query_params class ResponseSerializer(wsgi.JSONResponseSerializer): def __init__(self, task_schema=None, partial_task_schema=None): super(ResponseSerializer, self).__init__() self.task_schema = task_schema or get_task_schema() self.partial_task_schema = partial_task_schema \ or _get_partial_task_schema() def _inject_location_header(self, response, task): location = self._get_task_location(task) response.headers['Location'] = location.encode('utf-8') def _get_task_location(self, task): return '/v2/tasks/%s' % task.task_id def _format_task(self, schema, task, task_details=None): task_view = {} task_attributes = ['type', 'status', 'owner'] task_details_attributes = ['input', 'result', 'message'] for key in task_attributes: task_view[key] = getattr(task, key) if task_details: for key in task_details_attributes: task_view[key] = getattr(task_details, key) task_view['id'] = task.task_id if task.expires_at: task_view['expires_at'] = timeutils.isotime(task.expires_at) task_view['created_at'] = timeutils.isotime(task.created_at) task_view['updated_at'] = timeutils.isotime(task.updated_at) task_view['self'] = self._get_task_location(task) task_view['schema'] = '/v2/schemas/task' task_view = schema.filter(task_view) # domain return task_view def create(self, response, result): response.status_int = 201 task = result['task'] task_details = result['task_details'] self._inject_location_header(response, task) self._get(response, task, task_details) def get(self, response, result): task = result['task'] task_details = result['task_details'] self._get(response, task, task_details) def _get(self, response, task, task_details): task_view = self._format_task(self.task_schema, task, task_details) body = json.dumps(task_view, ensure_ascii=False) response.unicode_body = unicode(body) response.content_type = 'application/json' def index(self, response, result): params = dict(response.request.params) params.pop('marker', None) query = urlparse.urlencode(params) body = { 'tasks': [self._format_task(self.partial_task_schema, task) for task in result['tasks']], 'first': '/v2/tasks', 'schema': '/v2/schemas/tasks', } if query: body['first'] = '%s?%s' % (body['first'], query) if 'next_marker' in result: params['marker'] = result['next_marker'] next_query = urlparse.urlencode(params) body['next'] = '/v2/tasks?%s' % next_query response.unicode_body = unicode(json.dumps(body, ensure_ascii=False)) response.content_type = 'application/json' _TASK_SCHEMA = { "id": { "description": _("An identifier for the task"), "pattern": _('^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}' '-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}$'), "type": "string" }, "type": { "description": _("The type of task represented by this content"), "enum": [ "import", ], "type": "string" }, "status": { "description": _("The current status of this task"), "enum": [ "pending", "processing", "success", "failure" ], "type": "string" }, "input": { "description": _("The parameters required by task, JSON blob"), "type": "object" }, "result": { "description": _("The result of current task, JSON blob"), "type": "object", }, "owner": { "description": _("An identifier for the owner of this task"), "type": "string" }, "message": { "description": _("Human-readable informative message only included" " when appropriate (usually on failure)"), "type": "string", }, "expires_at": { "description": _("Datetime when this resource would be" " subject to removal"), "type": "string" }, "created_at": { "description": _("Datetime when this resource was created"), "type": "string" }, "updated_at": { "description": _("Datetime when this resource was updated"), "type": "string" }, 'self': {'type': 'string'}, 'schema': {'type': 'string'} } def get_task_schema(): properties = copy.deepcopy(_TASK_SCHEMA) schema = glance.schema.Schema('task', properties) return schema def _get_partial_task_schema(): properties = copy.deepcopy(_TASK_SCHEMA) hide_properties = ['input', 'result', 'message'] for key in hide_properties: del properties[key] schema = glance.schema.Schema('task', properties) return schema def get_collection_schema(): task_schema = _get_partial_task_schema() return glance.schema.CollectionSchema('tasks', task_schema) def create_resource(): """Task resource factory method""" task_schema = get_task_schema() partial_task_schema = _get_partial_task_schema() deserializer = RequestDeserializer(task_schema) serializer = ResponseSerializer(task_schema, partial_task_schema) controller = TasksController() return wsgi.Resource(controller, deserializer, serializer) glance-2014.1/glance/api/v2/image_members.py0000664000175400017540000002667412323736226021714 0ustar jenkinsjenkins00000000000000# Copyright 2013 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import copy import webob from glance.api import policy from glance.common import exception from glance.common import utils from glance.common import wsgi import glance.db import glance.gateway import glance.notifier from glance.openstack.common import jsonutils from glance.openstack.common import timeutils import glance.schema import glance.store class ImageMembersController(object): def __init__(self, db_api=None, policy_enforcer=None, notifier=None, store_api=None): self.db_api = db_api or glance.db.get_api() self.policy = policy_enforcer or policy.Enforcer() self.notifier = notifier or glance.notifier.Notifier() self.store_api = store_api or glance.store self.gateway = glance.gateway.Gateway(self.db_api, self.store_api, self.notifier, self.policy) @utils.mutating def create(self, req, image_id, member_id): """ Adds a membership to the image. :param req: the Request object coming from the wsgi layer :param image_id: the image identifier :param member_id: the member identifier :retval The response body is a mapping of the following form:: {'member_id': , 'image_id': , 'status': 'created_at': .., 'updated_at': ..} """ image_repo = self.gateway.get_repo(req.context) image_member_factory = self.gateway\ .get_image_member_factory(req.context) try: image = image_repo.get(image_id) member_repo = image.get_member_repo() new_member = image_member_factory.new_image_member(image, member_id) member_repo.add(new_member) return new_member except exception.NotFound as e: raise webob.exc.HTTPNotFound(explanation=e.msg) except exception.Forbidden as e: raise webob.exc.HTTPForbidden(explanation=e.msg) except exception.Duplicate as e: raise webob.exc.HTTPConflict(explanation=e.msg) except exception.ImageMemberLimitExceeded as e: raise webob.exc.HTTPRequestEntityTooLarge(explanation=e.msg) @utils.mutating def update(self, req, image_id, member_id, status): """ Adds a membership to the image. :param req: the Request object coming from the wsgi layer :param image_id: the image identifier :param member_id: the member identifier :retval The response body is a mapping of the following form:: {'member_id': , 'image_id': , 'status': 'created_at': .., 'updated_at': ..} """ image_repo = self.gateway.get_repo(req.context) try: image = image_repo.get(image_id) member_repo = image.get_member_repo() member = member_repo.get(member_id) member.status = status member_repo.save(member) return member except exception.NotFound as e: raise webob.exc.HTTPNotFound(explanation=e.msg) except exception.Forbidden as e: raise webob.exc.HTTPForbidden(explanation=e.msg) except ValueError as e: raise webob.exc.HTTPBadRequest(explanation=unicode(e)) def index(self, req, image_id): """ Return a list of dictionaries indicating the members of the image, i.e., those tenants the image is shared with. :param req: the Request object coming from the wsgi layer :param image_id: The image identifier :retval The response body is a mapping of the following form:: {'members': [ {'member_id': , 'image_id': , 'status': 'created_at': .., 'updated_at': ..}, .. ]} """ image_repo = self.gateway.get_repo(req.context) try: image = image_repo.get(image_id) member_repo = image.get_member_repo() members = [] for member in member_repo.list(): members.append(member) return dict(members=members) except exception.NotFound as e: raise webob.exc.HTTPNotFound(explanation=e.msg) except exception.Forbidden as e: raise webob.exc.HTTPForbidden(explanation=e.msg) def show(self, req, image_id, member_id): """ Returns the membership of the tenant wrt to the image_id specified. :param req: the Request object coming from the wsgi layer :param image_id: The image identifier :retval The response body is a mapping of the following form:: {'member_id': , 'image_id': , 'status': 'created_at': .., 'updated_at': ..} """ image_repo = self.gateway.get_repo(req.context) try: image = image_repo.get(image_id) member_repo = image.get_member_repo() member = member_repo.get(member_id) return member except (exception.NotFound, exception.Forbidden) as e: raise webob.exc.HTTPNotFound(explanation=e.msg) @utils.mutating def delete(self, req, image_id, member_id): """ Removes a membership from the image. """ image_repo = self.gateway.get_repo(req.context) try: image = image_repo.get(image_id) member_repo = image.get_member_repo() member = member_repo.get(member_id) member_repo.remove(member) return webob.Response(body='', status=204) except exception.NotFound as e: raise webob.exc.HTTPNotFound(explanation=e.msg) except exception.Forbidden as e: raise webob.exc.HTTPForbidden(explanation=e.msg) class RequestDeserializer(wsgi.JSONRequestDeserializer): def __init__(self): super(RequestDeserializer, self).__init__() def _get_request_body(self, request): output = super(RequestDeserializer, self).default(request) if 'body' not in output: msg = _('Body expected in request.') raise webob.exc.HTTPBadRequest(explanation=msg) return output['body'] def create(self, request): body = self._get_request_body(request) try: member_id = body['member'] if not member_id: raise ValueError() except KeyError: msg = _("Member to be added not specified") raise webob.exc.HTTPBadRequest(explanation=msg) except ValueError: msg = _("Member can't be empty") raise webob.exc.HTTPBadRequest(explanation=msg) return dict(member_id=member_id) def update(self, request): body = self._get_request_body(request) try: status = body['status'] except KeyError: msg = _("Status not specified") raise webob.exc.HTTPBadRequest(explanation=msg) return dict(status=status) class ResponseSerializer(wsgi.JSONResponseSerializer): def __init__(self, schema=None): super(ResponseSerializer, self).__init__() self.schema = schema or get_schema() def _format_image_member(self, member): member_view = {} attributes = ['member_id', 'image_id', 'status'] for key in attributes: member_view[key] = getattr(member, key) member_view['created_at'] = timeutils.isotime(member.created_at) member_view['updated_at'] = timeutils.isotime(member.updated_at) member_view['schema'] = '/v2/schemas/member' member_view = self.schema.filter(member_view) return member_view def create(self, response, image_member): image_member_view = self._format_image_member(image_member) body = jsonutils.dumps(image_member_view, ensure_ascii=False) response.unicode_body = unicode(body) response.content_type = 'application/json' def update(self, response, image_member): image_member_view = self._format_image_member(image_member) body = jsonutils.dumps(image_member_view, ensure_ascii=False) response.unicode_body = unicode(body) response.content_type = 'application/json' def index(self, response, image_members): image_members = image_members['members'] image_members_view = [] for image_member in image_members: image_member_view = self._format_image_member(image_member) image_members_view.append(image_member_view) totalview = dict(members=image_members_view) totalview['schema'] = '/v2/schemas/members' body = jsonutils.dumps(totalview, ensure_ascii=False) response.unicode_body = unicode(body) response.content_type = 'application/json' def show(self, response, image_member): image_member_view = self._format_image_member(image_member) body = jsonutils.dumps(image_member_view, ensure_ascii=False) response.unicode_body = unicode(body) response.content_type = 'application/json' _MEMBER_SCHEMA = { 'member_id': { 'type': 'string', 'description': _('An identifier for the image member (tenantId)') }, 'image_id': { 'type': 'string', 'description': _('An identifier for the image'), 'pattern': ('^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}' '-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}$'), }, 'created_at': { 'type': 'string', 'description': _('Date and time of image member creation'), #TODO(brian-rosmaita): our jsonschema library doesn't seem to like the # format attribute, figure out why (and also fix in images.py) #'format': 'date-time', }, 'updated_at': { 'type': 'string', 'description': _('Date and time of last modification of image member'), #'format': 'date-time', }, 'status': { 'type': 'string', 'description': _('The status of this image member'), 'enum': [ 'pending', 'accepted', 'rejected' ] }, 'schema': {'type': 'string'} } def get_schema(): properties = copy.deepcopy(_MEMBER_SCHEMA) schema = glance.schema.Schema('member', properties) return schema def get_collection_schema(): member_schema = get_schema() return glance.schema.CollectionSchema('members', member_schema) def create_resource(): """Image Members resource factory method""" deserializer = RequestDeserializer() serializer = ResponseSerializer() controller = ImageMembersController() return wsgi.Resource(controller, deserializer, serializer) glance-2014.1/glance/api/v2/image_data.py0000664000175400017540000001742612323736230021161 0ustar jenkinsjenkins00000000000000# Copyright 2012 OpenStack Foundation. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import webob.exc import glance.api.policy from glance.common import exception from glance.common import utils from glance.common import wsgi import glance.db import glance.gateway import glance.notifier import glance.openstack.common.log as logging import glance.store LOG = logging.getLogger(__name__) class ImageDataController(object): def __init__(self, db_api=None, store_api=None, policy_enforcer=None, notifier=None, gateway=None): if gateway is None: db_api = db_api or glance.db.get_api() store_api = store_api or glance.store policy = policy_enforcer or glance.api.policy.Enforcer() notifier = notifier or glance.notifier.Notifier() gateway = glance.gateway.Gateway(db_api, store_api, notifier, policy) self.gateway = gateway def _restore(self, image_repo, image): """ Restore the image to queued status. :param image_repo: The instance of ImageRepo :param image: The image will be restored """ try: if image_repo and image: image.status = 'queued' image_repo.save(image) except Exception as e: msg = _("Unable to restore image %(image_id)s: %(e)s") % \ {'image_id': image.image_id, 'e': unicode(e)} LOG.exception(msg) @utils.mutating def upload(self, req, image_id, data, size): image_repo = self.gateway.get_repo(req.context) try: image = image_repo.get(image_id) image.status = 'saving' try: image_repo.save(image) image.set_data(data, size) image_repo.save(image) except exception.NotFound as e: msg = (_("Image %(id)s could not be found after upload." "The image may have been deleted during the upload: " "%(error)s Cleaning up the chunks uploaded") % {'id': image_id, 'error': e}) LOG.warn(msg) # NOTE(sridevi): Cleaning up the uploaded chunks. try: image.delete() except exception.NotFound: # NOTE(sridevi): Ignore this exception pass raise webob.exc.HTTPGone(explanation=msg, request=req, content_type='text/plain') except ValueError as e: LOG.debug("Cannot save data for image %s: %s", image_id, e) self._restore(image_repo, image) raise webob.exc.HTTPBadRequest(explanation=unicode(e)) except exception.InvalidImageStatusTransition as e: msg = unicode(e) LOG.debug(msg) raise webob.exc.HTTPConflict(explanation=e.msg, request=req) except exception.Forbidden as e: msg = (_("Not allowed to upload image data for image %s") % image_id) LOG.debug(msg) raise webob.exc.HTTPForbidden(explanation=msg, request=req) except exception.NotFound as e: raise webob.exc.HTTPNotFound(explanation=e.msg) except exception.StorageFull as e: msg = _("Image storage media is full: %s") % e LOG.error(msg) self._restore(image_repo, image) raise webob.exc.HTTPRequestEntityTooLarge(explanation=msg, request=req) except exception.StorageQuotaFull as e: msg = _("Image exceeds the storage quota: %s") % e LOG.error(msg) self._restore(image_repo, image) raise webob.exc.HTTPRequestEntityTooLarge(explanation=msg, request=req) except exception.ImageSizeLimitExceeded as e: msg = _("The incoming image is too large: %s") % e LOG.error(msg) self._restore(image_repo, image) raise webob.exc.HTTPRequestEntityTooLarge(explanation=msg, request=req) except exception.StorageWriteDenied as e: msg = _("Insufficient permissions on image storage media: %s") % e LOG.error(msg) self._restore(image_repo, image) raise webob.exc.HTTPServiceUnavailable(explanation=msg, request=req) except webob.exc.HTTPError as e: LOG.error(_("Failed to upload image data due to HTTP error")) self._restore(image_repo, image) raise except Exception as e: LOG.exception(_("Failed to upload image data due to " "internal error")) self._restore(image_repo, image) raise def download(self, req, image_id): image_repo = self.gateway.get_repo(req.context) try: image = image_repo.get(image_id) if not image.locations: raise exception.ImageDataNotFound() except exception.ImageDataNotFound as e: raise webob.exc.HTTPNoContent(explanation=e.msg) except exception.NotFound as e: raise webob.exc.HTTPNotFound(explanation=e.msg) except exception.Forbidden as e: raise webob.exc.HTTPForbidden(explanation=e.msg) return image class RequestDeserializer(wsgi.JSONRequestDeserializer): def upload(self, request): try: request.get_content_type(('application/octet-stream',)) except exception.InvalidContentType as e: raise webob.exc.HTTPUnsupportedMediaType(explanation=e.msg) image_size = request.content_length or None return {'size': image_size, 'data': request.body_file} class ResponseSerializer(wsgi.JSONResponseSerializer): def download(self, response, image): response.headers['Content-Type'] = 'application/octet-stream' try: # NOTE(markwash): filesystem store (and maybe others?) cause a # problem with the caching middleware if they are not wrapped in # an iterator very strange response.app_iter = iter(image.get_data()) except exception.Forbidden as e: raise webob.exc.HTTPForbidden(explanation=e.msg) #NOTE(saschpe): "response.app_iter = ..." currently resets Content-MD5 # (https://github.com/Pylons/webob/issues/86), so it should be set # afterwards for the time being. if image.checksum: response.headers['Content-MD5'] = image.checksum #NOTE(markwash): "response.app_iter = ..." also erroneously resets the # content-length response.headers['Content-Length'] = str(image.size) def upload(self, response, result): response.status_int = 204 def create_resource(): """Image data resource factory method""" deserializer = RequestDeserializer() serializer = ResponseSerializer() controller = ImageDataController() return wsgi.Resource(controller, deserializer, serializer) glance-2014.1/glance/api/v2/router.py0000664000175400017540000001404412323736226020424 0ustar jenkinsjenkins00000000000000# Copyright 2012 OpenStack Foundation. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from glance.api.v2 import image_data from glance.api.v2 import image_members from glance.api.v2 import image_tags from glance.api.v2 import images from glance.api.v2 import schemas from glance.api.v2 import tasks from glance.common import wsgi class API(wsgi.Router): """WSGI router for Glance v2 API requests.""" def __init__(self, mapper): custom_image_properties = images.load_custom_properties() schemas_resource = schemas.create_resource(custom_image_properties) mapper.connect('/schemas/image', controller=schemas_resource, action='image', conditions={'method': ['GET']}) mapper.connect('/schemas/images', controller=schemas_resource, action='images', conditions={'method': ['GET']}) mapper.connect('/schemas/member', controller=schemas_resource, action='member', conditions={'method': ['GET']}) mapper.connect('/schemas/members', controller=schemas_resource, action='members', conditions={'method': ['GET']}) mapper.connect('/schemas/task', controller=schemas_resource, action='task', conditions={'method': ['GET']}) mapper.connect('/schemas/tasks', controller=schemas_resource, action='tasks', conditions={'method': ['GET']}) images_resource = images.create_resource(custom_image_properties) mapper.connect('/images', controller=images_resource, action='index', conditions={'method': ['GET']}) mapper.connect('/images', controller=images_resource, action='create', conditions={'method': ['POST']}) mapper.connect('/images/{image_id}', controller=images_resource, action='update', conditions={'method': ['PATCH']}) mapper.connect('/images/{image_id}', controller=images_resource, action='show', conditions={'method': ['GET']}) mapper.connect('/images/{image_id}', controller=images_resource, action='delete', conditions={'method': ['DELETE']}) image_data_resource = image_data.create_resource() mapper.connect('/images/{image_id}/file', controller=image_data_resource, action='download', conditions={'method': ['GET']}) mapper.connect('/images/{image_id}/file', controller=image_data_resource, action='upload', conditions={'method': ['PUT']}) image_tags_resource = image_tags.create_resource() mapper.connect('/images/{image_id}/tags/{tag_value}', controller=image_tags_resource, action='update', conditions={'method': ['PUT']}) mapper.connect('/images/{image_id}/tags/{tag_value}', controller=image_tags_resource, action='delete', conditions={'method': ['DELETE']}) image_members_resource = image_members.create_resource() mapper.connect('/images/{image_id}/members', controller=image_members_resource, action='index', conditions={'method': ['GET']}) mapper.connect('/images/{image_id}/members/{member_id}', controller=image_members_resource, action='show', conditions={'method': ['GET']}) mapper.connect('/images/{image_id}/members/{member_id}', controller=image_members_resource, action='update', conditions={'method': ['PUT']}) mapper.connect('/images/{image_id}/members', controller=image_members_resource, action='create', conditions={'method': ['POST']}) mapper.connect('/images/{image_id}/members/{member_id}', controller=image_members_resource, action='delete', conditions={'method': ['DELETE']}) tasks_resource = tasks.create_resource() mapper.connect('/tasks', controller=tasks_resource, action='create', conditions={'method': ['POST']}) mapper.connect('/tasks', controller=tasks_resource, action='index', conditions={'method': ['GET']}) mapper.connect('/tasks/{task_id}', controller=tasks_resource, action='get', conditions={'method': ['GET']}) mapper.connect('/tasks/{task_id}', controller=tasks_resource, action='delete', conditions={'method': ['DELETE']}) super(API, self).__init__(mapper) glance-2014.1/glance/api/v2/__init__.py0000664000175400017540000000000012323736226020626 0ustar jenkinsjenkins00000000000000glance-2014.1/glance/api/__init__.py0000664000175400017540000000170112323736226020310 0ustar jenkinsjenkins00000000000000# Copyright 2011-2012 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from oslo.config import cfg import paste.urlmap CONF = cfg.CONF def root_app_factory(loader, global_conf, **local_conf): if not CONF.enable_v1_api: del local_conf['/v1'] if not CONF.enable_v2_api: del local_conf['/v2'] return paste.urlmap.urlmap_factory(loader, global_conf, **local_conf) glance-2014.1/glance/api/v1/0000775000175400017540000000000012323736427016531 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/api/v1/upload_utils.py0000664000175400017540000002372712323736230021612 0ustar jenkinsjenkins00000000000000# Copyright 2013 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from oslo.config import cfg import webob.exc from glance.common import exception from glance.common import utils import glance.db from glance.openstack.common import excutils import glance.openstack.common.log as logging import glance.registry.client.v1.api as registry import glance.store CONF = cfg.CONF LOG = logging.getLogger(__name__) def initiate_deletion(req, location, id, delayed_delete=False): """ Deletes image data from the backend store. :param req: The WSGI/Webob Request object :param location: URL to the image data in a data store :param image_id: Opaque image identifier :param delayed_delete: whether data deletion will be delayed """ if delayed_delete: glance.store.schedule_delayed_delete_from_backend(req.context, location, id) else: glance.store.safe_delete_from_backend(req.context, location, id) def _kill(req, image_id): """ Marks the image status to `killed`. :param req: The WSGI/Webob Request object :param image_id: Opaque image identifier """ registry.update_image_metadata(req.context, image_id, {'status': 'killed'}) def safe_kill(req, image_id): """ Mark image killed without raising exceptions if it fails. Since _kill is meant to be called from exceptions handlers, it should not raise itself, rather it should just log its error. :param req: The WSGI/Webob Request object :param image_id: Opaque image identifier """ try: _kill(req, image_id) except Exception: LOG.exception(_("Unable to kill image %(id)s: ") % {'id': image_id}) def upload_data_to_store(req, image_meta, image_data, store, notifier): """ Upload image data to specified store. Upload image data to the store and cleans up on error. """ image_id = image_meta['id'] db_api = glance.db.get_api() image_size = image_meta.get('size') try: remaining = glance.api.common.check_quota( req.context, image_size, db_api, image_id=image_id) if remaining is not None: image_data = utils.LimitingReader(image_data, remaining) (location, size, checksum, locations_metadata) = glance.store.store_add_to_backend( image_meta['id'], utils.CooperativeReader(image_data), image_meta['size'], store) try: # recheck the quota in case there were simultaneous uploads that # did not provide the size glance.api.common.check_quota( req.context, size, db_api, image_id=image_id) except exception.StorageQuotaFull: LOG.info(_('Cleaning up %s after exceeding the quota') % image_id) glance.store.safe_delete_from_backend( location, req.context, image_meta['id']) raise def _kill_mismatched(image_meta, attr, actual): supplied = image_meta.get(attr) if supplied and supplied != actual: msg = (_("Supplied %(attr)s (%(supplied)s) and " "%(attr)s generated from uploaded image " "(%(actual)s) did not match. Setting image " "status to 'killed'.") % {'attr': attr, 'supplied': supplied, 'actual': actual}) LOG.error(msg) safe_kill(req, image_id) initiate_deletion(req, location, image_id, CONF.delayed_delete) raise webob.exc.HTTPBadRequest(explanation=msg, content_type="text/plain", request=req) # Verify any supplied size/checksum value matches size/checksum # returned from store when adding image _kill_mismatched(image_meta, 'size', size) _kill_mismatched(image_meta, 'checksum', checksum) # Update the database with the checksum returned # from the backend store LOG.debug(_("Updating image %(image_id)s data. " "Checksum set to %(checksum)s, size set " "to %(size)d"), {'image_id': image_id, 'checksum': checksum, 'size': size}) update_data = {'checksum': checksum, 'size': size} try: image_meta = registry.update_image_metadata(req.context, image_id, update_data) except exception.NotFound as e: msg = _("Image %s could not be found after upload. The image may " "have been deleted during the upload.") % image_id LOG.info(msg) # NOTE(jculp): we need to clean up the datastore if an image # resource is deleted while the image data is being uploaded # # We get "location" from above call to store.add(), any # exceptions that occur there handle this same issue internally, # Since this is store-agnostic, should apply to all stores. initiate_deletion(req, location, image_id, CONF.delayed_delete) raise webob.exc.HTTPPreconditionFailed(explanation=msg, request=req, content_type='text/plain') except exception.Duplicate as e: msg = _("Attempt to upload duplicate image: %s") % e LOG.debug(msg) # NOTE(dosaboy): do not delete the image since it is likely that this # conflict is a result of another concurrent upload that will be # successful. notifier.error('image.upload', msg) raise webob.exc.HTTPConflict(explanation=msg, request=req, content_type="text/plain") except exception.Forbidden as e: msg = _("Forbidden upload attempt: %s") % e LOG.debug(msg) safe_kill(req, image_id) notifier.error('image.upload', msg) raise webob.exc.HTTPForbidden(explanation=msg, request=req, content_type="text/plain") except exception.StorageFull as e: msg = _("Image storage media is full: %s") % e LOG.error(msg) safe_kill(req, image_id) notifier.error('image.upload', msg) raise webob.exc.HTTPRequestEntityTooLarge(explanation=msg, request=req, content_type='text/plain') except exception.StorageWriteDenied as e: msg = _("Insufficient permissions on image storage media: %s") % e LOG.error(msg) safe_kill(req, image_id) notifier.error('image.upload', msg) raise webob.exc.HTTPServiceUnavailable(explanation=msg, request=req, content_type='text/plain') except exception.ImageSizeLimitExceeded as e: msg = (_("Denying attempt to upload image larger than %d bytes.") % CONF.image_size_cap) LOG.info(msg) safe_kill(req, image_id) notifier.error('image.upload', msg) raise webob.exc.HTTPRequestEntityTooLarge(explanation=msg, request=req, content_type='text/plain') except exception.StorageQuotaFull as e: msg = (_("Denying attempt to upload image because it exceeds the ." "quota: %s") % e) LOG.info(msg) safe_kill(req, image_id) notifier.error('image.upload', msg) raise webob.exc.HTTPRequestEntityTooLarge(explanation=msg, request=req, content_type='text/plain') except webob.exc.HTTPError: #NOTE(bcwaldon): Ideally, we would just call 'raise' here, # but something in the above function calls is affecting the # exception context and we must explicitly re-raise the # caught exception. msg = _("Received HTTP error while uploading image %s") % image_id notifier.error('image.upload', msg) with excutils.save_and_reraise_exception(): LOG.exception(msg) safe_kill(req, image_id) except (ValueError, IOError) as e: msg = _("Client disconnected before sending all data to backend") LOG.debug(msg) safe_kill(req, image_id) raise webob.exc.HTTPBadRequest(explanation=msg, content_type="text/plain", request=req) except Exception as e: msg = _("Failed to upload image %s") % image_id LOG.exception(msg) safe_kill(req, image_id) notifier.error('image.upload', msg) raise webob.exc.HTTPInternalServerError(explanation=msg, request=req, content_type='text/plain') return image_meta, location, locations_metadata glance-2014.1/glance/api/v1/images.py0000664000175400017540000014224112323736230020344 0ustar jenkinsjenkins00000000000000# Copyright 2013 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ /images endpoint for Glance v1 API """ import copy import eventlet from oslo.config import cfg import six.moves.urllib.parse as urlparse from webob.exc import HTTPBadRequest from webob.exc import HTTPConflict from webob.exc import HTTPForbidden from webob.exc import HTTPNotFound from webob.exc import HTTPRequestEntityTooLarge from webob import Response from glance.api import common from glance.api import policy import glance.api.v1 from glance.api.v1 import controller from glance.api.v1 import filters from glance.api.v1 import upload_utils from glance.common import exception from glance.common import property_utils from glance.common import utils from glance.common import wsgi from glance import notifier import glance.openstack.common.log as logging from glance.openstack.common import strutils import glance.registry.client.v1.api as registry from glance.store import get_from_backend from glance.store import get_known_schemes from glance.store import get_known_stores from glance.store import get_size_from_backend from glance.store import get_store_from_location from glance.store import get_store_from_scheme LOG = logging.getLogger(__name__) SUPPORTED_PARAMS = glance.api.v1.SUPPORTED_PARAMS SUPPORTED_FILTERS = glance.api.v1.SUPPORTED_FILTERS ACTIVE_IMMUTABLE = glance.api.v1.ACTIVE_IMMUTABLE CONF = cfg.CONF CONF.import_opt('disk_formats', 'glance.common.config', group='image_format') CONF.import_opt('container_formats', 'glance.common.config', group='image_format') CONF.import_opt('image_property_quota', 'glance.common.config') def validate_image_meta(req, values): name = values.get('name') disk_format = values.get('disk_format') container_format = values.get('container_format') if 'disk_format' in values: if disk_format not in CONF.image_format.disk_formats: msg = _("Invalid disk format '%s' for image.") % disk_format raise HTTPBadRequest(explanation=msg, request=req) if 'container_format' in values: if container_format not in CONF.image_format.container_formats: msg = _("Invalid container format '%s' " "for image.") % container_format raise HTTPBadRequest(explanation=msg, request=req) if name and len(name) > 255: msg = _('Image name too long: %d') % len(name) raise HTTPBadRequest(explanation=msg, request=req) amazon_formats = ('aki', 'ari', 'ami') if disk_format in amazon_formats or container_format in amazon_formats: if disk_format is None: values['disk_format'] = container_format elif container_format is None: values['container_format'] = disk_format elif container_format != disk_format: msg = (_("Invalid mix of disk and container formats. " "When setting a disk or container format to " "one of 'aki', 'ari', or 'ami', the container " "and disk formats must match.")) raise HTTPBadRequest(explanation=msg, request=req) return values def redact_loc(image_meta, copy_dict=True): """ Create a shallow copy of image meta with 'location' removed for security (as it can contain credentials). """ if copy_dict: new_image_meta = copy.copy(image_meta) else: new_image_meta = image_meta new_image_meta.pop('location', None) new_image_meta.pop('location_data', None) return new_image_meta class Controller(controller.BaseController): """ WSGI controller for images resource in Glance v1 API The images resource API is a RESTful web service for image data. The API is as follows:: GET /images -- Returns a set of brief metadata about images GET /images/detail -- Returns a set of detailed metadata about images HEAD /images/ -- Return metadata about an image with id GET /images/ -- Return image data for image with id POST /images -- Store image data and return metadata about the newly-stored image PUT /images/ -- Update image metadata and/or upload image data for a previously-reserved image DELETE /images/ -- Delete the image with id """ def __init__(self): self.notifier = notifier.Notifier() registry.configure_registry_client() self.policy = policy.Enforcer() self.pool = eventlet.GreenPool(size=1024) if property_utils.is_property_protection_enabled(): self.prop_enforcer = property_utils.PropertyRules(self.policy) else: self.prop_enforcer = None def _enforce(self, req, action): """Authorize an action against our policies""" try: self.policy.enforce(req.context, action, {}) except exception.Forbidden: raise HTTPForbidden() def _enforce_image_property_quota(self, image_meta, orig_image_meta=None, purge_props=False, req=None): if CONF.image_property_quota < 0: # If value is negative, allow unlimited number of properties return props = image_meta['properties'].keys() # NOTE(ameade): If we are not removing existing properties, # take them in to account if (not purge_props) and orig_image_meta: original_props = orig_image_meta['properties'].keys() props.extend(original_props) props = set(props) if len(props) > CONF.image_property_quota: msg = (_("The limit has been exceeded on the number of allowed " "image properties. Attempted: %(num)s, Maximum: " "%(quota)s") % {'num': len(props), 'quota': CONF.image_property_quota}) LOG.info(msg) raise HTTPRequestEntityTooLarge(explanation=msg, request=req, content_type="text/plain") def _enforce_create_protected_props(self, create_props, req): """ Check request is permitted to create certain properties :param create_props: List of properties to check :param req: The WSGI/Webob Request object :raises HTTPForbidden if request forbidden to create a property """ if property_utils.is_property_protection_enabled(): for key in create_props: if (self.prop_enforcer.check_property_rules( key, 'create', req.context) is False): msg = _("Property '%s' is protected") % key LOG.debug(msg) raise HTTPForbidden(explanation=msg, request=req, content_type="text/plain") def _enforce_read_protected_props(self, image_meta, req): """ Remove entries from metadata properties if they are read protected :param image_meta: Mapping of metadata about image :param req: The WSGI/Webob Request object """ if property_utils.is_property_protection_enabled(): for key in image_meta['properties'].keys(): if (self.prop_enforcer.check_property_rules( key, 'read', req.context) is False): image_meta['properties'].pop(key) def _enforce_update_protected_props(self, update_props, image_meta, orig_meta, req): """ Check request is permitted to update certain properties. Read permission is required to delete a property. If the property value is unchanged, i.e. a noop, it is permitted, however, it is important to ensure read access first. Otherwise the value could be discovered using brute force. :param update_props: List of properties to check :param image_meta: Mapping of proposed new metadata about image :param orig_meta: Mapping of existing metadata about image :param req: The WSGI/Webob Request object :raises HTTPForbidden if request forbidden to create a property """ if property_utils.is_property_protection_enabled(): for key in update_props: has_read = self.prop_enforcer.check_property_rules( key, 'read', req.context) if ((self.prop_enforcer.check_property_rules( key, 'update', req.context) is False and image_meta['properties'][key] != orig_meta['properties'][key]) or not has_read): msg = _("Property '%s' is protected") % key LOG.debug(msg) raise HTTPForbidden(explanation=msg, request=req, content_type="text/plain") def _enforce_delete_protected_props(self, delete_props, image_meta, orig_meta, req): """ Check request is permitted to delete certain properties. Read permission is required to delete a property. Note, the absence of a property in a request does not necessarily indicate a delete. The requester may not have read access, and so can not know the property exists. Hence, read access is a requirement for delete, otherwise the delete is ignored transparently. :param delete_props: List of properties to check :param image_meta: Mapping of proposed new metadata about image :param orig_meta: Mapping of existing metadata about image :param req: The WSGI/Webob Request object :raises HTTPForbidden if request forbidden to create a property """ if property_utils.is_property_protection_enabled(): for key in delete_props: if (self.prop_enforcer.check_property_rules( key, 'read', req.context) is False): # NOTE(bourke): if read protected, re-add to image_meta to # prevent deletion image_meta['properties'][key] = \ orig_meta['properties'][key] elif (self.prop_enforcer.check_property_rules( key, 'delete', req.context) is False): msg = _("Property '%s' is protected") % key LOG.debug(msg) raise HTTPForbidden(explanation=msg, request=req, content_type="text/plain") def index(self, req): """ Returns the following information for all public, available images: * id -- The opaque image identifier * name -- The name of the image * disk_format -- The disk image format * container_format -- The "container" format of the image * checksum -- MD5 checksum of the image data * size -- Size of image data in bytes :param req: The WSGI/Webob Request object :retval The response body is a mapping of the following form:: {'images': [ {'id': , 'name': , 'disk_format': , 'container_format': , 'checksum': 'size': }, ... ]} """ self._enforce(req, 'get_images') params = self._get_query_params(req) try: images = registry.get_images_list(req.context, **params) except exception.Invalid as e: raise HTTPBadRequest(explanation="%s" % e) return dict(images=images) def detail(self, req): """ Returns detailed information for all available images :param req: The WSGI/Webob Request object :retval The response body is a mapping of the following form:: {'images': [ {'id': , 'name': , 'size': , 'disk_format': , 'container_format': , 'checksum': , 'min_disk': , 'min_ram': , 'store': , 'status': , 'created_at': , 'updated_at': , 'deleted_at': |, 'properties': {'distro': 'Ubuntu 10.04 LTS', ...}}, ... ]} """ self._enforce(req, 'get_images') params = self._get_query_params(req) try: images = registry.get_images_detail(req.context, **params) # Strip out the Location attribute. Temporary fix for # LP Bug #755916. This information is still coming back # from the registry, since the API server still needs access # to it, however we do not return this potential security # information to the API end user... for image in images: redact_loc(image, copy_dict=False) self._enforce_read_protected_props(image, req) except exception.Invalid as e: raise HTTPBadRequest(explanation="%s" % e) return dict(images=images) def _get_query_params(self, req): """ Extracts necessary query params from request. :param req: the WSGI Request object :retval dict of parameters that can be used by registry client """ params = {'filters': self._get_filters(req)} for PARAM in SUPPORTED_PARAMS: if PARAM in req.params: params[PARAM] = req.params.get(PARAM) # Fix for LP Bug #1132294 # Ensure all shared images are returned in v1 params['member_status'] = 'all' return params def _get_filters(self, req): """ Return a dictionary of query param filters from the request :param req: the Request object coming from the wsgi layer :retval a dict of key/value filters """ query_filters = {} for param in req.params: if param in SUPPORTED_FILTERS or param.startswith('property-'): query_filters[param] = req.params.get(param) if not filters.validate(param, query_filters[param]): raise HTTPBadRequest(_('Bad value passed to filter ' '%(filter)s got %(val)s') % {'filter': param, 'val': query_filters[param]}) return query_filters def meta(self, req, id): """ Returns metadata about an image in the HTTP headers of the response object :param req: The WSGI/Webob Request object :param id: The opaque image identifier :retval similar to 'show' method but without image_data :raises HTTPNotFound if image metadata is not available to user """ self._enforce(req, 'get_image') image_meta = self.get_image_meta_or_404(req, id) image_meta = redact_loc(image_meta) self._enforce_read_protected_props(image_meta, req) return { 'image_meta': image_meta } @staticmethod def _validate_source(source, req): """ External sources (as specified via the location or copy-from headers) are supported only over non-local store types, i.e. S3, Swift, HTTP. Note the absence of file:// for security reasons, see LP bug #942118. If the above constraint is violated, we reject with 400 "Bad Request". """ if source: pieces = urlparse.urlparse(source) schemes = [scheme for scheme in get_known_schemes() if scheme != 'file'] for scheme in schemes: if pieces.scheme == scheme: return source msg = _("External sourcing not supported for store %s") % source LOG.debug(msg) raise HTTPBadRequest(explanation=msg, request=req, content_type="text/plain") @staticmethod def _copy_from(req): return req.headers.get('x-glance-api-copy-from') def _external_source(self, image_meta, req): source = image_meta.get('location') if source is not None: self._enforce(req, 'set_image_location') else: source = Controller._copy_from(req) return Controller._validate_source(source, req) @staticmethod def _get_from_store(context, where): try: image_data, image_size = get_from_backend(context, where) except exception.NotFound as e: raise HTTPNotFound(explanation=e.msg) image_size = int(image_size) if image_size else None return image_data, image_size def show(self, req, id): """ Returns an iterator that can be used to retrieve an image's data along with the image metadata. :param req: The WSGI/Webob Request object :param id: The opaque image identifier :raises HTTPNotFound if image is not available to user """ self._enforce(req, 'get_image') self._enforce(req, 'download_image') image_meta = self.get_active_image_meta_or_404(req, id) self._enforce_read_protected_props(image_meta, req) if image_meta.get('size') == 0: image_iterator = iter([]) else: image_iterator, size = self._get_from_store(req.context, image_meta['location']) image_iterator = utils.cooperative_iter(image_iterator) image_meta['size'] = size or image_meta['size'] image_meta = redact_loc(image_meta) return { 'image_iterator': image_iterator, 'image_meta': image_meta, } def _reserve(self, req, image_meta): """ Adds the image metadata to the registry and assigns an image identifier if one is not supplied in the request headers. Sets the image's status to `queued`. :param req: The WSGI/Webob Request object :param id: The opaque image identifier :param image_meta: The image metadata :raises HTTPConflict if image already exists :raises HTTPBadRequest if image metadata is not valid """ location = self._external_source(image_meta, req) store = image_meta.get('store') if store and store not in get_known_stores(): msg = _("Required store %s is invalid") % store LOG.debug(msg) raise HTTPBadRequest(explanation=msg, content_type='text/plain') image_meta['status'] = ('active' if image_meta.get('size') == 0 else 'queued') if location: try: store = get_store_from_location(location) except exception.BadStoreUri: msg = _("Invalid location %s") % location LOG.debug(msg) raise HTTPBadRequest(explanation=msg, request=req, content_type="text/plain") # check the store exists before we hit the registry, but we # don't actually care what it is at this point self.get_store_or_400(req, store) # retrieve the image size from remote store (if not provided) image_meta['size'] = self._get_size(req.context, image_meta, location) else: # Ensure that the size attribute is set to zero for directly # uploadable images (if not provided). The size will be set # to a non-zero value during upload image_meta['size'] = image_meta.get('size', 0) try: image_meta = registry.add_image_metadata(req.context, image_meta) self.notifier.info("image.create", redact_loc(image_meta)) return image_meta except exception.Duplicate: msg = (_("An image with identifier %s already exists") % image_meta['id']) LOG.debug(msg) raise HTTPConflict(explanation=msg, request=req, content_type="text/plain") except exception.Invalid as e: msg = _("Failed to reserve image. Got error: %(e)s") % {'e': e} for line in msg.split('\n'): LOG.debug(line) raise HTTPBadRequest(explanation=msg, request=req, content_type="text/plain") except exception.Forbidden: msg = _("Forbidden to reserve image.") LOG.debug(msg) raise HTTPForbidden(explanation=msg, request=req, content_type="text/plain") def _upload(self, req, image_meta): """ Uploads the payload of the request to a backend store in Glance. If the `x-image-meta-store` header is set, Glance will attempt to use that scheme; if not, Glance will use the scheme set by the flag `default_store` to find the backing store. :param req: The WSGI/Webob Request object :param image_meta: Mapping of metadata about image :raises HTTPConflict if image already exists :retval The location where the image was stored """ copy_from = self._copy_from(req) if copy_from: try: image_data, image_size = self._get_from_store(req.context, copy_from) except Exception as e: upload_utils.safe_kill(req, image_meta['id']) msg = _("Copy from external source failed: %s") % e LOG.debug(msg) return image_meta['size'] = image_size or image_meta['size'] else: try: req.get_content_type(('application/octet-stream',)) except exception.InvalidContentType: upload_utils.safe_kill(req, image_meta['id']) msg = _("Content-Type must be application/octet-stream") LOG.debug(msg) raise HTTPBadRequest(explanation=msg) image_data = req.body_file scheme = req.headers.get('x-image-meta-store', CONF.default_store) store = self.get_store_or_400(req, scheme) image_id = image_meta['id'] LOG.debug(_("Setting image %s to status 'saving'"), image_id) registry.update_image_metadata(req.context, image_id, {'status': 'saving'}) LOG.debug(_("Uploading image data for image %(image_id)s " "to %(scheme)s store"), {'image_id': image_id, 'scheme': scheme}) self.notifier.info("image.prepare", redact_loc(image_meta)) image_meta, location, loc_meta = upload_utils.upload_data_to_store( req, image_meta, image_data, store, self.notifier) self.notifier.info('image.upload', redact_loc(image_meta)) return location, loc_meta def _activate(self, req, image_id, location, location_metadata=None, from_state=None): """ Sets the image status to `active` and the image's location attribute. :param req: The WSGI/Webob Request object :param image_id: Opaque image identifier :param location: Location of where Glance stored this image :param location_metadata: a dictionary of storage specific information """ image_meta = {} image_meta['location'] = location image_meta['status'] = 'active' if location_metadata: image_meta['location_data'] = [{'url': location, 'metadata': location_metadata}] try: s = from_state image_meta_data = registry.update_image_metadata(req.context, image_id, image_meta, from_state=s) self.notifier.info("image.activate", redact_loc(image_meta_data)) self.notifier.info("image.update", redact_loc(image_meta_data)) return image_meta_data except exception.Duplicate: # Delete image data since it has been supersceded by another # upload. LOG.debug(_("duplicate operation - deleting image data for %(id)s " "(location:%(location)s)") % {'id': image_id, 'location': image_meta['location']}) upload_utils.initiate_deletion(req, image_meta['location'], image_id, CONF.delayed_delete) # Then propagate the exception. raise except exception.Invalid as e: msg = _("Failed to activate image. Got error: %(e)s") % {'e': e} LOG.debug(msg) raise HTTPBadRequest(explanation=msg, request=req, content_type="text/plain") def _upload_and_activate(self, req, image_meta): """ Safely uploads the image data in the request payload and activates the image in the registry after a successful upload. :param req: The WSGI/Webob Request object :param image_meta: Mapping of metadata about image :retval Mapping of updated image data """ image_id = image_meta['id'] # This is necessary because of a bug in Webob 1.0.2 - 1.0.7 # See: https://bitbucket.org/ianb/webob/ # issue/12/fix-for-issue-6-broke-chunked-transfer req.is_body_readable = True location, location_metadata = self._upload(req, image_meta) return self._activate(req, image_id, location, location_metadata, from_state='saving') if location else None def _get_size(self, context, image_meta, location): # retrieve the image size from remote store (if not provided) return image_meta.get('size', 0) or get_size_from_backend(context, location) def _handle_source(self, req, image_id, image_meta, image_data): copy_from = self._copy_from(req) location = image_meta.get('location') sources = filter(lambda x: x, (copy_from, location, image_data)) if len(sources) >= 2: msg = _("It's invalid to provide multiple image sources.") LOG.debug(msg) raise HTTPBadRequest(explanation=msg, request=req, content_type="text/plain") if image_data: image_meta = self._validate_image_for_activation(req, image_id, image_meta) image_meta = self._upload_and_activate(req, image_meta) elif copy_from: msg = _('Triggering asynchronous copy from external source') LOG.info(msg) self.pool.spawn_n(self._upload_and_activate, req, image_meta) else: if location: self._validate_image_for_activation(req, image_id, image_meta) image_size_meta = image_meta.get('size') if image_size_meta: image_size_store = get_size_from_backend(req.context, location) # NOTE(zhiyan): A returned size of zero usually means # the driver encountered an error. In this case the # size provided by the client will be used as-is. if (image_size_store and image_size_store != image_size_meta): msg = _("Provided image size must match the stored " "image size. (provided size: %(ps)d, " "stored size: %(ss)d)") % { "ps": image_size_meta, "ss": image_size_store} LOG.debug(msg) raise HTTPConflict(explanation=msg, request=req, content_type="text/plain") image_meta = self._activate(req, image_id, location) return image_meta def _validate_image_for_activation(self, req, id, values): """Ensures that all required image metadata values are valid.""" image = self.get_image_meta_or_404(req, id) if 'disk_format' not in values: values['disk_format'] = image['disk_format'] if 'container_format' not in values: values['container_format'] = image['container_format'] if 'name' not in values: values['name'] = image['name'] values = validate_image_meta(req, values) return values @utils.mutating def create(self, req, image_meta, image_data): """ Adds a new image to Glance. Four scenarios exist when creating an image: 1. If the image data is available directly for upload, create can be passed the image data as the request body and the metadata as the request headers. The image will initially be 'queued', during upload it will be in the 'saving' status, and then 'killed' or 'active' depending on whether the upload completed successfully. 2. If the image data exists somewhere else, you can upload indirectly from the external source using the x-glance-api-copy-from header. Once the image is uploaded, the external store is not subsequently consulted, i.e. the image content is served out from the configured glance image store. State transitions are as for option #1. 3. If the image data exists somewhere else, you can reference the source using the x-image-meta-location header. The image content will be served out from the external store, i.e. is never uploaded to the configured glance image store. 4. If the image data is not available yet, but you'd like reserve a spot for it, you can omit the data and a record will be created in the 'queued' state. This exists primarily to maintain backwards compatibility with OpenStack/Rackspace API semantics. The request body *must* be encoded as application/octet-stream, otherwise an HTTPBadRequest is returned. Upon a successful save of the image data and metadata, a response containing metadata about the image is returned, including its opaque identifier. :param req: The WSGI/Webob Request object :param image_meta: Mapping of metadata about image :param image_data: Actual image data that is to be stored :raises HTTPBadRequest if x-image-meta-location is missing and the request body is not application/octet-stream image data. """ self._enforce(req, 'add_image') is_public = image_meta.get('is_public') if is_public: self._enforce(req, 'publicize_image') if Controller._copy_from(req): self._enforce(req, 'copy_from') if image_data or Controller._copy_from(req): self._enforce(req, 'upload_image') self._enforce_create_protected_props(image_meta['properties'].keys(), req) self._enforce_image_property_quota(image_meta, req=req) image_meta = self._reserve(req, image_meta) id = image_meta['id'] image_meta = self._handle_source(req, id, image_meta, image_data) location_uri = image_meta.get('location') if location_uri: self.update_store_acls(req, id, location_uri, public=is_public) # Prevent client from learning the location, as it # could contain security credentials image_meta = redact_loc(image_meta) return {'image_meta': image_meta} @utils.mutating def update(self, req, id, image_meta, image_data): """ Updates an existing image with the registry. :param request: The WSGI/Webob Request object :param id: The opaque image identifier :retval Returns the updated image information as a mapping """ self._enforce(req, 'modify_image') is_public = image_meta.get('is_public') if is_public: self._enforce(req, 'publicize_image') if Controller._copy_from(req): self._enforce(req, 'copy_from') if image_data or Controller._copy_from(req): self._enforce(req, 'upload_image') orig_image_meta = self.get_image_meta_or_404(req, id) orig_status = orig_image_meta['status'] # Do not allow any updates on a deleted image. # Fix for LP Bug #1060930 if orig_status == 'deleted': msg = _("Forbidden to update deleted image.") raise HTTPForbidden(explanation=msg, request=req, content_type="text/plain") if req.context.is_admin is False: # Once an image is 'active' only an admin can # modify certain core metadata keys for key in ACTIVE_IMMUTABLE: if (orig_status == 'active' and image_meta.get(key) is not None and image_meta.get(key) != orig_image_meta.get(key)): msg = _("Forbidden to modify '%s' of active image.") % key raise HTTPForbidden(explanation=msg, request=req, content_type="text/plain") # The default behaviour for a PUT /images/ is to # override any properties that were previously set. This, however, # leads to a number of issues for the common use case where a caller # registers an image with some properties and then almost immediately # uploads an image file along with some more properties. Here, we # check for a special header value to be false in order to force # properties NOT to be purged. However we also disable purging of # properties if an image file is being uploaded... purge_props = req.headers.get('x-glance-registry-purge-props', True) purge_props = (strutils.bool_from_string(purge_props) and image_data is None) if image_data is not None and orig_status != 'queued': raise HTTPConflict(_("Cannot upload to an unqueued image")) # Only allow the Location|Copy-From fields to be modified if the # image is in queued status, which indicates that the user called # POST /images but originally supply neither a Location|Copy-From # field NOR image data location = self._external_source(image_meta, req) reactivating = orig_status != 'queued' and location activating = orig_status == 'queued' and (location or image_data) # Make image public in the backend store (if implemented) orig_or_updated_loc = location or orig_image_meta.get('location') if orig_or_updated_loc: try: self.update_store_acls(req, id, orig_or_updated_loc, public=is_public) except exception.BadStoreUri: msg = _("Invalid location %s") % location LOG.debug(msg) raise HTTPBadRequest(explanation=msg, request=req, content_type="text/plain") if reactivating: msg = _("Attempted to update Location field for an image " "not in queued status.") raise HTTPBadRequest(explanation=msg, request=req, content_type="text/plain") # ensure requester has permissions to create/update/delete properties # according to property-protections.conf orig_keys = set(orig_image_meta['properties']) new_keys = set(image_meta['properties']) self._enforce_update_protected_props( orig_keys.intersection(new_keys), image_meta, orig_image_meta, req) self._enforce_create_protected_props( new_keys.difference(orig_keys), req) if purge_props: self._enforce_delete_protected_props( orig_keys.difference(new_keys), image_meta, orig_image_meta, req) self._enforce_image_property_quota(image_meta, orig_image_meta=orig_image_meta, purge_props=purge_props, req=req) try: if location: image_meta['size'] = self._get_size(req.context, image_meta, location) image_meta = registry.update_image_metadata(req.context, id, image_meta, purge_props) if activating: image_meta = self._handle_source(req, id, image_meta, image_data) except exception.Invalid as e: msg = (_("Failed to update image metadata. Got error: %(e)s") % {'e': e}) LOG.debug(msg) raise HTTPBadRequest(explanation=msg, request=req, content_type="text/plain") except exception.NotFound as e: msg = _("Failed to find image to update: %(e)s") % {'e': e} for line in msg.split('\n'): LOG.info(line) raise HTTPNotFound(explanation=msg, request=req, content_type="text/plain") except exception.Forbidden as e: msg = _("Forbidden to update image: %(e)s") % {'e': e} for line in msg.split('\n'): LOG.info(line) raise HTTPForbidden(explanation=msg, request=req, content_type="text/plain") except (exception.Conflict, exception.Duplicate) as e: LOG.info(unicode(e)) raise HTTPConflict(body='Image operation conflicts', request=req, content_type='text/plain') else: self.notifier.info('image.update', redact_loc(image_meta)) # Prevent client from learning the location, as it # could contain security credentials image_meta = redact_loc(image_meta) self._enforce_read_protected_props(image_meta, req) return {'image_meta': image_meta} @utils.mutating def delete(self, req, id): """ Deletes the image and all its chunks from the Glance :param req: The WSGI/Webob Request object :param id: The opaque image identifier :raises HttpBadRequest if image registry is invalid :raises HttpNotFound if image or any chunk is not available :raises HttpUnauthorized if image or any chunk is not deleteable by the requesting user """ self._enforce(req, 'delete_image') image = self.get_image_meta_or_404(req, id) if image['protected']: msg = _("Image is protected") LOG.debug(msg) raise HTTPForbidden(explanation=msg, request=req, content_type="text/plain") if image['status'] == 'pending_delete': msg = (_("Forbidden to delete a %s image.") % image['status']) LOG.debug(msg) raise HTTPForbidden(explanation=msg, request=req, content_type="text/plain") elif image['status'] == 'deleted': msg = _("Image %s not found.") % id LOG.debug(msg) raise HTTPNotFound(explanation=msg, request=req, content_type="text/plain") if image['location'] and CONF.delayed_delete: status = 'pending_delete' else: status = 'deleted' ori_status = image['status'] try: # Update the image from the registry first, since we rely on it # for authorization checks. # See https://bugs.launchpad.net/glance/+bug/1065187 image = registry.update_image_metadata(req.context, id, {'status': status}) try: # The image's location field may be None in the case # of a saving or queued image, therefore don't ask a backend # to delete the image if the backend doesn't yet store it. # See https://bugs.launchpad.net/glance/+bug/747799 if image['location']: upload_utils.initiate_deletion(req, image['location'], id, CONF.delayed_delete) except Exception as e: registry.update_image_metadata(req.context, id, {'status': ori_status}) raise e registry.delete_image_metadata(req.context, id) except exception.NotFound as e: msg = _("Failed to find image to delete: %(e)s") % {'e': e} for line in msg.split('\n'): LOG.info(line) raise HTTPNotFound(explanation=msg, request=req, content_type="text/plain") except exception.Forbidden as e: msg = _("Forbidden to delete image: %(e)s") % {'e': e} for line in msg.split('\n'): LOG.info(line) raise HTTPForbidden(explanation=msg, request=req, content_type="text/plain") else: self.notifier.info('image.delete', redact_loc(image)) return Response(body='', status=200) def get_store_or_400(self, request, scheme): """ Grabs the storage backend for the supplied store name or raises an HTTPBadRequest (400) response :param request: The WSGI/Webob Request object :param scheme: The backend store scheme :raises HTTPNotFound if store does not exist """ try: return get_store_from_scheme(request.context, scheme) except exception.UnknownScheme: msg = _("Store for scheme %s not found") % scheme LOG.debug(msg) raise HTTPBadRequest(explanation=msg, request=request, content_type='text/plain') class ImageDeserializer(wsgi.JSONRequestDeserializer): """Handles deserialization of specific controller method requests.""" def _deserialize(self, request): result = {} try: result['image_meta'] = utils.get_image_meta_from_headers(request) except exception.InvalidParameterValue as e: msg = unicode(e) LOG.warn(msg, exc_info=True) raise HTTPBadRequest(explanation=e.msg, request=request) image_meta = result['image_meta'] image_meta = validate_image_meta(request, image_meta) if request.content_length: image_size = request.content_length elif 'size' in image_meta: image_size = image_meta['size'] else: image_size = None data = request.body_file if self.has_body(request) else None if image_size is None and data is not None: data = utils.LimitingReader(data, CONF.image_size_cap) #NOTE(bcwaldon): this is a hack to make sure the downstream code # gets the correct image data request.body_file = data elif image_size > CONF.image_size_cap: max_image_size = CONF.image_size_cap msg = _("Denying attempt to upload image larger than %d bytes.") LOG.warn(msg % max_image_size) raise HTTPBadRequest(explanation=msg % max_image_size, request=request) result['image_data'] = data return result def create(self, request): return self._deserialize(request) def update(self, request): return self._deserialize(request) class ImageSerializer(wsgi.JSONResponseSerializer): """Handles serialization of specific controller method responses.""" def __init__(self): self.notifier = notifier.Notifier() def _inject_location_header(self, response, image_meta): location = self._get_image_location(image_meta) response.headers['Location'] = location.encode('utf-8') def _inject_checksum_header(self, response, image_meta): if image_meta['checksum'] is not None: response.headers['ETag'] = image_meta['checksum'].encode('utf-8') def _inject_image_meta_headers(self, response, image_meta): """ Given a response and mapping of image metadata, injects the Response with a set of HTTP headers for the image metadata. Each main image metadata field is injected as a HTTP header with key 'x-image-meta-' except for the properties field, which is further broken out into a set of 'x-image-meta-property-' headers :param response: The Webob Response object :param image_meta: Mapping of image metadata """ headers = utils.image_meta_to_http_headers(image_meta) for k, v in headers.items(): response.headers[k.encode('utf-8')] = v.encode('utf-8') def _get_image_location(self, image_meta): """Build a relative url to reach the image defined by image_meta.""" return "/v1/images/%s" % image_meta['id'] def meta(self, response, result): image_meta = result['image_meta'] self._inject_image_meta_headers(response, image_meta) self._inject_location_header(response, image_meta) self._inject_checksum_header(response, image_meta) return response def show(self, response, result): image_meta = result['image_meta'] image_iter = result['image_iterator'] # image_meta['size'] should be an int, but could possibly be a str expected_size = int(image_meta['size']) response.app_iter = common.size_checked_iter( response, image_meta, expected_size, image_iter, self.notifier) # Using app_iter blanks content-length, so we set it here... response.headers['Content-Length'] = str(image_meta['size']) response.headers['Content-Type'] = 'application/octet-stream' self._inject_image_meta_headers(response, image_meta) self._inject_location_header(response, image_meta) self._inject_checksum_header(response, image_meta) return response def update(self, response, result): image_meta = result['image_meta'] response.body = self.to_json(dict(image=image_meta)) response.headers['Content-Type'] = 'application/json' self._inject_location_header(response, image_meta) self._inject_checksum_header(response, image_meta) return response def create(self, response, result): image_meta = result['image_meta'] response.status = 201 response.headers['Content-Type'] = 'application/json' response.body = self.to_json(dict(image=image_meta)) self._inject_location_header(response, image_meta) self._inject_checksum_header(response, image_meta) return response def create_resource(): """Images resource factory method""" deserializer = ImageDeserializer() serializer = ImageSerializer() return wsgi.Resource(Controller(), deserializer, serializer) glance-2014.1/glance/api/v1/members.py0000664000175400017540000002144612323736226020541 0ustar jenkinsjenkins00000000000000# Copyright 2012 OpenStack Foundation. # Copyright 2013 NTT corp. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from oslo.config import cfg import six import webob.exc from glance.api import policy from glance.api.v1 import controller from glance.common import exception from glance.common import utils from glance.common import wsgi import glance.openstack.common.log as logging import glance.registry.client.v1.api as registry LOG = logging.getLogger(__name__) CONF = cfg.CONF CONF.import_opt('image_member_quota', 'glance.common.config') class Controller(controller.BaseController): def __init__(self): self.policy = policy.Enforcer() def _check_can_access_image_members(self, context): if context.owner is None and not context.is_admin: raise webob.exc.HTTPUnauthorized(_("No authenticated user")) def _enforce(self, req, action): """Authorize an action against our policies""" try: self.policy.enforce(req.context, action, {}) except exception.Forbidden: raise webob.exc.HTTPForbidden() def _raise_404_if_image_deleted(self, req, image_id): image = self.get_image_meta_or_404(req, image_id) if image['status'] == 'deleted': msg = _("Image with identifier %s has been deleted.") % image_id raise webob.exc.HTTPNotFound(msg) def index(self, req, image_id): """ Return a list of dictionaries indicating the members of the image, i.e., those tenants the image is shared with. :param req: the Request object coming from the wsgi layer :param image_id: The opaque image identifier :retval The response body is a mapping of the following form:: {'members': [ {'member_id': , 'can_share': , ...}, ... ]} """ self._enforce(req, 'get_members') self._raise_404_if_image_deleted(req, image_id) try: members = registry.get_image_members(req.context, image_id) except exception.NotFound: msg = _("Image with identifier %s not found") % image_id LOG.debug(msg) raise webob.exc.HTTPNotFound(msg) except exception.Forbidden: msg = _("Unauthorized image access") LOG.debug(msg) raise webob.exc.HTTPForbidden(msg) return dict(members=members) @utils.mutating def delete(self, req, image_id, id): """ Removes a membership from the image. """ self._check_can_access_image_members(req.context) self._enforce(req, 'delete_member') self._raise_404_if_image_deleted(req, image_id) try: registry.delete_member(req.context, image_id, id) self._update_store_acls(req, image_id) except exception.NotFound as e: LOG.debug(six.text_type(e)) raise webob.exc.HTTPNotFound(explanation=e.msg) except exception.Forbidden as e: LOG.debug(six.text_type(e)) raise webob.exc.HTTPNotFound(explanation=e.msg) return webob.exc.HTTPNoContent() def default(self, req, image_id, id, body=None): """This will cover the missing 'show' and 'create' actions""" raise webob.exc.HTTPMethodNotAllowed() def _enforce_image_member_quota(self, req, attempted): if CONF.image_member_quota < 0: # If value is negative, allow unlimited number of members return maximum = CONF.image_member_quota if attempted > maximum: msg = _("The limit has been exceeded on the number of allowed " "image members for this image. Attempted: %(attempted)s, " "Maximum: %(maximum)s") % {'attempted': attempted, 'maximum': maximum} raise webob.exc.HTTPRequestEntityTooLarge(explanation=msg, request=req) @utils.mutating def update(self, req, image_id, id, body=None): """ Adds a membership to the image, or updates an existing one. If a body is present, it is a dict with the following format:: {"member": { "can_share": [True|False] }} If "can_share" is provided, the member's ability to share is set accordingly. If it is not provided, existing memberships remain unchanged and new memberships default to False. """ self._check_can_access_image_members(req.context) self._enforce(req, 'modify_member') self._raise_404_if_image_deleted(req, image_id) new_number_of_members = len(registry.get_image_members(req.context, image_id)) + 1 self._enforce_image_member_quota(req, new_number_of_members) # Figure out can_share can_share = None if body and 'member' in body and 'can_share' in body['member']: can_share = bool(body['member']['can_share']) try: registry.add_member(req.context, image_id, id, can_share) self._update_store_acls(req, image_id) except exception.Invalid as e: LOG.debug(six.text_type(e)) raise webob.exc.HTTPBadRequest(explanation=e.msg) except exception.NotFound as e: LOG.debug(six.text_type(e)) raise webob.exc.HTTPNotFound(explanation=e.msg) except exception.Forbidden as e: LOG.debug(six.text_type(e)) raise webob.exc.HTTPNotFound(explanation=e.msg) return webob.exc.HTTPNoContent() @utils.mutating def update_all(self, req, image_id, body): """ Replaces the members of the image with those specified in the body. The body is a dict with the following format:: {"memberships": [ {"member_id": , ["can_share": [True|False]]}, ... ]} """ self._check_can_access_image_members(req.context) self._enforce(req, 'modify_member') self._raise_404_if_image_deleted(req, image_id) memberships = body.get('memberships') if memberships: new_number_of_members = len(body['memberships']) self._enforce_image_member_quota(req, new_number_of_members) try: registry.replace_members(req.context, image_id, body) self._update_store_acls(req, image_id) except exception.Invalid as e: LOG.debug(six.text_type(e)) raise webob.exc.HTTPBadRequest(explanation=e.msg) except exception.NotFound as e: LOG.debug(six.text_type(e)) raise webob.exc.HTTPNotFound(explanation=e.msg) except exception.Forbidden as e: LOG.debug(six.text_type(e)) raise webob.exc.HTTPNotFound(explanation=e.msg) return webob.exc.HTTPNoContent() def index_shared_images(self, req, id): """ Retrieves list of image memberships for the given member. :param req: the Request object coming from the wsgi layer :param id: the opaque member identifier :retval The response body is a mapping of the following form:: {'shared_images': [ {'image_id': , 'can_share': , ...}, ... ]} """ try: members = registry.get_member_images(req.context, id) except exception.NotFound as e: LOG.debug(six.text_type(e)) raise webob.exc.HTTPNotFound(explanation=e.msg) except exception.Forbidden as e: LOG.debug(six.text_type(e)) raise webob.exc.HTTPForbidden(explanation=e.msg) return dict(shared_images=members) def _update_store_acls(self, req, image_id): image_meta = self.get_image_meta_or_404(req, image_id) location_uri = image_meta.get('location') public = image_meta.get('is_public') self.update_store_acls(req, image_id, location_uri, public) def create_resource(): """Image members resource factory method""" deserializer = wsgi.JSONRequestDeserializer() serializer = wsgi.JSONResponseSerializer() return wsgi.Resource(Controller(), deserializer, serializer) glance-2014.1/glance/api/v1/filters.py0000664000175400017540000000255312323736226020555 0ustar jenkinsjenkins00000000000000# Copyright 2012, Piston Cloud Computing, 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. def validate(filter, value): return FILTER_FUNCTIONS.get(filter, lambda v: True)(value) def validate_int_in_range(min=0, max=None): def _validator(v): try: if max is None: return min <= int(v) return min <= int(v) <= max except ValueError: return False return _validator def validate_boolean(v): return v.lower() in ('none', 'true', 'false', '1', '0') FILTER_FUNCTIONS = {'size_max': validate_int_in_range(), # build validator 'size_min': validate_int_in_range(), # build validator 'min_ram': validate_int_in_range(), # build validator 'protected': validate_boolean, 'is_public': validate_boolean, } glance-2014.1/glance/api/v1/router.py0000664000175400017540000000676712323736230020433 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from glance.api.v1 import images from glance.api.v1 import members from glance.common import wsgi class API(wsgi.Router): """WSGI router for Glance v1 API requests.""" def __init__(self, mapper): images_resource = images.create_resource() mapper.connect("/", controller=images_resource, action="index") mapper.connect("/images", controller=images_resource, action='index', conditions={'method': ['GET']}) mapper.connect("/images", controller=images_resource, action='create', conditions={'method': ['POST']}) mapper.connect("/images/detail", controller=images_resource, action='detail', conditions={'method': ['GET']}) mapper.connect("/images/{id}", controller=images_resource, action="meta", conditions=dict(method=["HEAD"])) mapper.connect("/images/{id}", controller=images_resource, action="show", conditions=dict(method=["GET"])) mapper.connect("/images/{id}", controller=images_resource, action="update", conditions=dict(method=["PUT"])) mapper.connect("/images/{id}", controller=images_resource, action="delete", conditions=dict(method=["DELETE"])) members_resource = members.create_resource() mapper.connect("/images/{image_id}/members", controller=members_resource, action="index", conditions={'method': ['GET']}) mapper.connect("/images/{image_id}/members", controller=members_resource, action="update_all", conditions=dict(method=["PUT"])) mapper.connect("/images/{image_id}/members/{id}", controller=members_resource, action="show", conditions={'method': ['GET']}) mapper.connect("/images/{image_id}/members/{id}", controller=members_resource, action="update", conditions={'method': ['PUT']}) mapper.connect("/images/{image_id}/members/{id}", controller=members_resource, action="delete", conditions={'method': ['DELETE']}) mapper.connect("/shared-images/{id}", controller=members_resource, action="index_shared_images") super(API, self).__init__(mapper) glance-2014.1/glance/api/v1/controller.py0000664000175400017540000000656512323736226021277 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import webob.exc from glance.common import exception import glance.openstack.common.log as logging import glance.registry.client.v1.api as registry import glance.store as store LOG = logging.getLogger(__name__) class BaseController(object): def get_image_meta_or_404(self, request, image_id): """ Grabs the image metadata for an image with a supplied identifier or raises an HTTPNotFound (404) response :param request: The WSGI/Webob Request object :param image_id: The opaque image identifier :raises HTTPNotFound if image does not exist """ context = request.context try: return registry.get_image_metadata(context, image_id) except exception.NotFound: msg = _("Image with identifier %s not found") % image_id LOG.debug(msg) raise webob.exc.HTTPNotFound( msg, request=request, content_type='text/plain') except exception.Forbidden: msg = _("Forbidden image access") LOG.debug(msg) raise webob.exc.HTTPForbidden(msg, request=request, content_type='text/plain') def get_active_image_meta_or_404(self, request, image_id): """ Same as get_image_meta_or_404 except that it will raise a 404 if the image isn't 'active'. """ image = self.get_image_meta_or_404(request, image_id) if image['status'] != 'active': msg = _("Image %s is not active") % image_id LOG.debug(msg) raise webob.exc.HTTPNotFound( msg, request=request, content_type='text/plain') return image def update_store_acls(self, req, image_id, location_uri, public=False): if location_uri: try: read_tenants = [] write_tenants = [] members = registry.get_image_members(req.context, image_id) if members: for member in members: if member['can_share']: write_tenants.append(member['member_id']) else: read_tenants.append(member['member_id']) store.set_acls(req.context, location_uri, public=public, read_tenants=read_tenants, write_tenants=write_tenants) except exception.UnknownScheme: msg = _("Store for image_id not found: %s") % image_id raise webob.exc.HTTPBadRequest(explanation=msg, request=req, content_type='text/plain') glance-2014.1/glance/api/v1/__init__.py0000664000175400017540000000176612323736226020651 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. SUPPORTED_FILTERS = ['name', 'status', 'container_format', 'disk_format', 'min_ram', 'min_disk', 'size_min', 'size_max', 'is_public', 'changes-since', 'protected'] SUPPORTED_PARAMS = ('limit', 'marker', 'sort_key', 'sort_dir') # Metadata which only an admin can change once the image is active ACTIVE_IMMUTABLE = ('size', 'checksum') glance-2014.1/glance/api/property_protections.py0000664000175400017540000001174012323736226023072 0ustar jenkinsjenkins00000000000000# Copyright 2013 Rackspace # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from glance.common import exception import glance.domain.proxy class ProtectedImageFactoryProxy(glance.domain.proxy.ImageFactory): def __init__(self, image_factory, context, property_rules): self.image_factory = image_factory self.context = context self.property_rules = property_rules kwargs = {'context': self.context, 'property_rules': self.property_rules} super(ProtectedImageFactoryProxy, self).__init__( image_factory, proxy_class=ProtectedImageProxy, proxy_kwargs=kwargs) def new_image(self, **kwargs): extra_props = kwargs.pop('extra_properties', {}) extra_properties = {} for key in extra_props.keys(): if self.property_rules.check_property_rules(key, 'create', self.context): extra_properties[key] = extra_props[key] else: raise exception.ReservedProperty(property=key) return super(ProtectedImageFactoryProxy, self).\ new_image(extra_properties=extra_properties, **kwargs) class ProtectedImageRepoProxy(glance.domain.proxy.Repo): def __init__(self, image_repo, context, property_rules): self.context = context self.image_repo = image_repo self.property_rules = property_rules proxy_kwargs = {'context': self.context} super(ProtectedImageRepoProxy, self).__init__( image_repo, item_proxy_class=ProtectedImageProxy, item_proxy_kwargs=proxy_kwargs) def get(self, image_id): return ProtectedImageProxy(self.image_repo.get(image_id), self.context, self.property_rules) def list(self, *args, **kwargs): images = self.image_repo.list(*args, **kwargs) return [ProtectedImageProxy(image, self.context, self.property_rules) for image in images] class ProtectedImageProxy(glance.domain.proxy.Image): def __init__(self, image, context, property_rules): self.image = image self.context = context self.property_rules = property_rules self.image.extra_properties = ExtraPropertiesProxy( self.context, self.image.extra_properties, self.property_rules) super(ProtectedImageProxy, self).__init__(self.image) class ExtraPropertiesProxy(glance.domain.ExtraProperties): def __init__(self, context, extra_props, property_rules): self.context = context self.property_rules = property_rules extra_properties = {} for key in extra_props.keys(): if self.property_rules.check_property_rules(key, 'read', self.context): extra_properties[key] = extra_props[key] super(ExtraPropertiesProxy, self).__init__(extra_properties) def __getitem__(self, key): if self.property_rules.check_property_rules(key, 'read', self.context): return dict.__getitem__(self, key) else: raise KeyError def __setitem__(self, key, value): # NOTE(isethi): Exceptions are raised only for actions update, delete # and create, where the user proactively interacts with the properties. # A user cannot request to read a specific property, hence reads do # raise an exception try: if self.__getitem__(key): if self.property_rules.check_property_rules(key, 'update', self.context): return dict.__setitem__(self, key, value) else: raise exception.ReservedProperty(property=key) except KeyError: if self.property_rules.check_property_rules(key, 'create', self.context): return dict.__setitem__(self, key, value) else: raise exception.ReservedProperty(property=key) def __delitem__(self, key): if not super(ExtraPropertiesProxy, self).__getitem__(key): raise KeyError if self.property_rules.check_property_rules(key, 'delete', self.context): return dict.__delitem__(self, key) else: raise exception.ReservedProperty(property=key) glance-2014.1/glance/quota/0000775000175400017540000000000012323736427016563 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/quota/__init__.py0000664000175400017540000003107212323736230020667 0ustar jenkinsjenkins00000000000000# Copyright 2013, Red Hat, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import copy from oslo.config import cfg import glance.api.common import glance.common.exception as exception from glance.common import utils import glance.domain import glance.domain.proxy import glance.openstack.common.log as logging LOG = logging.getLogger(__name__) CONF = cfg.CONF CONF.import_opt('image_member_quota', 'glance.common.config') CONF.import_opt('image_property_quota', 'glance.common.config') CONF.import_opt('image_tag_quota', 'glance.common.config') def _enforce_image_tag_quota(tags): if CONF.image_tag_quota < 0: # If value is negative, allow unlimited number of tags return if not tags: return if len(tags) > CONF.image_tag_quota: raise exception.ImageTagLimitExceeded(attempted=len(tags), maximum=CONF.image_tag_quota) def _calc_required_size(context, image, locations): required_size = None if image.size: required_size = image.size * len(locations) else: for location in locations: size_from_backend = None try: size_from_backend = glance.store.get_size_from_backend( context, location['url']) except (exception.UnknownScheme, exception.NotFound): pass if size_from_backend: required_size = size_from_backend * len(locations) break return required_size def _enforce_image_location_quota(image, locations, is_setter=False): if CONF.image_location_quota < 0: # If value is negative, allow unlimited number of locations return attempted = len(image.locations) + len(locations) attempted = attempted if not is_setter else len(locations) maximum = CONF.image_location_quota if attempted > maximum: raise exception.ImageLocationLimitExceeded(attempted=attempted, maximum=maximum) class ImageRepoProxy(glance.domain.proxy.Repo): def __init__(self, image_repo, context, db_api): self.image_repo = image_repo self.db_api = db_api proxy_kwargs = {'db_api': db_api, 'context': context} super(ImageRepoProxy, self).__init__(image_repo, item_proxy_class=ImageProxy, item_proxy_kwargs=proxy_kwargs) def _enforce_image_property_quota(self, image): if CONF.image_property_quota < 0: # If value is negative, allow unlimited number of properties return attempted = len(image.extra_properties) maximum = CONF.image_property_quota if attempted > maximum: raise exception.ImagePropertyLimitExceeded(attempted=attempted, maximum=maximum) def save(self, image): self._enforce_image_property_quota(image) super(ImageRepoProxy, self).save(image) def add(self, image): self._enforce_image_property_quota(image) super(ImageRepoProxy, self).add(image) class ImageFactoryProxy(glance.domain.proxy.ImageFactory): def __init__(self, factory, context, db_api): proxy_kwargs = {'db_api': db_api, 'context': context} super(ImageFactoryProxy, self).__init__(factory, proxy_class=ImageProxy, proxy_kwargs=proxy_kwargs) def new_image(self, **kwargs): tags = kwargs.pop('tags', set([])) _enforce_image_tag_quota(tags) return super(ImageFactoryProxy, self).new_image(tags=tags, **kwargs) class QuotaImageTagsProxy(object): def __init__(self, orig_set): if orig_set is None: orig_set = set([]) self.tags = orig_set def add(self, item): self.tags.add(item) _enforce_image_tag_quota(self.tags) def __cast__(self, *args, **kwargs): return self.tags.__cast__(*args, **kwargs) def __contains__(self, *args, **kwargs): return self.tags.__contains__(*args, **kwargs) def __eq__(self, other): return self.tags == other def __iter__(self, *args, **kwargs): return self.tags.__iter__(*args, **kwargs) def __len__(self, *args, **kwargs): return self.tags.__len__(*args, **kwargs) def __getattr__(self, name): return getattr(self.tags, name) class ImageMemberFactoryProxy(glance.domain.proxy.ImageMembershipFactory): def __init__(self, member_factory, context, db_api): self.db_api = db_api self.context = context super(ImageMemberFactoryProxy, self).__init__( member_factory, image_proxy_class=ImageProxy, image_proxy_kwargs={}) def _enforce_image_member_quota(self, image): if CONF.image_member_quota < 0: # If value is negative, allow unlimited number of members return current_member_count = self.db_api.image_member_count(self.context, image.image_id) attempted = current_member_count + 1 maximum = CONF.image_member_quota if attempted > maximum: raise exception.ImageMemberLimitExceeded(attempted=attempted, maximum=maximum) def new_image_member(self, image, member_id): self._enforce_image_member_quota(image) return super(ImageMemberFactoryProxy, self).new_image_member(image, member_id) class QuotaImageLocationsProxy(object): def __init__(self, image, context, db_api): self.image = image self.context = context self.db_api = db_api self.locations = image.locations def __cast__(self, *args, **kwargs): return self.locations.__cast__(*args, **kwargs) def __contains__(self, *args, **kwargs): return self.locations.__contains__(*args, **kwargs) def __delitem__(self, *args, **kwargs): return self.locations.__delitem__(*args, **kwargs) def __delslice__(self, *args, **kwargs): return self.locations.__delslice__(*args, **kwargs) def __eq__(self, other): return self.locations == other def __getitem__(self, *args, **kwargs): return self.locations.__getitem__(*args, **kwargs) def __iadd__(self, other): if not hasattr(other, '__iter__'): raise TypeError() self._check_user_storage_quota(other) return self.locations.__iadd__(other) def __iter__(self, *args, **kwargs): return self.locations.__iter__(*args, **kwargs) def __len__(self, *args, **kwargs): return self.locations.__len__(*args, **kwargs) def __setitem__(self, key, value): return self.locations.__setitem__(key, value) def count(self, *args, **kwargs): return self.locations.count(*args, **kwargs) def index(self, *args, **kwargs): return self.locations.index(*args, **kwargs) def pop(self, *args, **kwargs): return self.locations.pop(*args, **kwargs) def remove(self, *args, **kwargs): return self.locations.remove(*args, **kwargs) def reverse(self, *args, **kwargs): return self.locations.reverse(*args, **kwargs) def _check_user_storage_quota(self, locations): required_size = _calc_required_size(self.context, self.image, locations) glance.api.common.check_quota(self.context, required_size, self.db_api) _enforce_image_location_quota(self.image, locations) def __copy__(self): return type(self)(self.image, self.context, self.db_api) def __deepcopy__(self, memo): # NOTE(zhiyan): Only copy location entries, others can be reused. self.image.locations = copy.deepcopy(self.locations, memo) return type(self)(self.image, self.context, self.db_api) def append(self, object): self._check_user_storage_quota([object]) return self.locations.append(object) def insert(self, index, object): self._check_user_storage_quota([object]) return self.locations.insert(index, object) def extend(self, iter): self._check_user_storage_quota(iter) return self.locations.extend(iter) class ImageProxy(glance.domain.proxy.Image): def __init__(self, image, context, db_api): self.image = image self.context = context self.db_api = db_api super(ImageProxy, self).__init__(image) def set_data(self, data, size=None): remaining = glance.api.common.check_quota( self.context, size, self.db_api, image_id=self.image.image_id) if remaining is not None: # NOTE(jbresnah) we are trying to enforce a quota, put a limit # reader on the data data = utils.LimitingReader(data, remaining) try: self.image.set_data(data, size=size) except exception.ImageSizeLimitExceeded: raise exception.StorageQuotaFull(image_size=size, remaining=remaining) # NOTE(jbresnah) If two uploads happen at the same time and neither # properly sets the size attribute[1] then there is a race condition # that will allow for the quota to be broken[2]. Thus we must recheck # the quota after the upload and thus after we know the size. # # Also, when an upload doesn't set the size properly then the call to # check_quota above returns None and so utils.LimitingReader is not # used above. Hence the store (e.g. filesystem store) may have to # download the entire file before knowing the actual file size. Here # also we need to check for the quota again after the image has been # downloaded to the store. # # [1] For e.g. when using chunked transfers the 'Content-Length' # header is not set. # [2] For e.g.: # - Upload 1 does not exceed quota but upload 2 exceeds quota. # Both uploads are to different locations # - Upload 2 completes before upload 1 and writes image.size. # - Immediately, upload 1 completes and (over)writes image.size # with the smaller size. # - Now, to glance, image has not exceeded quota but, in # reality, the quota has been exceeded. try: glance.api.common.check_quota( self.context, self.image.size, self.db_api, image_id=self.image.image_id) except exception.StorageQuotaFull: LOG.info(_('Cleaning up %s after exceeding the quota.') % self.image.image_id) location = self.image.locations[0]['url'] glance.store.safe_delete_from_backend( self.context, location, self.image.image_id) raise @property def tags(self): return QuotaImageTagsProxy(self.image.tags) @tags.setter def tags(self, value): _enforce_image_tag_quota(value) self.image.tags = value @property def locations(self): return QuotaImageLocationsProxy(self.image, self.context, self.db_api) @locations.setter def locations(self, value): _enforce_image_location_quota(self.image, value, is_setter=True) if not isinstance(value, (list, QuotaImageLocationsProxy)): raise exception.Invalid(_('Invalid locations: %s') % value) required_size = _calc_required_size(self.context, self.image, value) glance.api.common.check_quota( self.context, required_size, self.db_api, image_id=self.image.image_id) self.image.locations = value glance-2014.1/glance/scrubber.py0000664000175400017540000004737212323736226017625 0ustar jenkinsjenkins00000000000000# Copyright 2010 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import abc import calendar import eventlet import os import time from oslo.config import cfg from glance.common import crypt from glance.common import exception from glance.common import utils from glance import context from glance.openstack.common import lockutils import glance.openstack.common.log as logging import glance.registry.client.v1.api as registry LOG = logging.getLogger(__name__) scrubber_opts = [ cfg.StrOpt('scrubber_datadir', default='/var/lib/glance/scrubber', help=_('Directory that the scrubber will use to track ' 'information about what to delete. ' 'Make sure this is set in glance-api.conf and ' 'glance-scrubber.conf.')), cfg.IntOpt('scrub_time', default=0, help=_('The amount of time in seconds to delay before ' 'performing a delete.')), cfg.BoolOpt('cleanup_scrubber', default=False, help=_('A boolean that determines if the scrubber should ' 'clean up the files it uses for taking data. Only ' 'one server in your deployment should be designated ' 'the cleanup host.')), cfg.IntOpt('cleanup_scrubber_time', default=86400, help=_('Items must have a modified time that is older than ' 'this value in order to be candidates for cleanup.')) ] CONF = cfg.CONF CONF.register_opts(scrubber_opts) CONF.import_opt('metadata_encryption_key', 'glance.common.config') class ScrubQueue(object): """Image scrub queue base class. The queue contains image's location which need to delete from backend. """ def __init__(self): registry.configure_registry_client() registry.configure_registry_admin_creds() self.registry = registry.get_registry_client(context.RequestContext()) @abc.abstractmethod def add_location(self, image_id, uri, user_context=None): """Adding image location to scrub queue. :param image_id: The opaque image identifier :param uri: The opaque image location uri :param user_context: The user's request context """ pass @abc.abstractmethod def get_all_locations(self): """Returns a list of image id and location tuple from scrub queue. :retval a list of image id and location tuple from scrub queue """ pass @abc.abstractmethod def pop_all_locations(self): """Pop out a list of image id and location tuple from scrub queue. :retval a list of image id and location tuple from scrub queue """ pass @abc.abstractmethod def has_image(self, image_id): """Returns whether the queue contains an image or not. :param image_id: The opaque image identifier :retval a boolean value to inform including or not """ pass class ScrubFileQueue(ScrubQueue): """File-based image scrub queue class.""" def __init__(self): super(ScrubFileQueue, self).__init__() self.scrubber_datadir = CONF.scrubber_datadir utils.safe_mkdirs(self.scrubber_datadir) self.scrub_time = CONF.scrub_time self.metadata_encryption_key = CONF.metadata_encryption_key def _read_queue_file(self, file_path): """Reading queue file to loading deleted location and timestamp out. :param file_path: Queue file full path :retval a list of image location timestamp tuple from queue file """ uris = [] delete_times = [] try: with open(file_path, 'r') as f: while True: uri = f.readline().strip() if uri: uris.append(uri) delete_times.append(int(f.readline().strip())) else: break except Exception: LOG.error(_("%s file can not be read.") % file_path) return uris, delete_times def _update_queue_file(self, file_path, remove_record_idxs): """Updating queue file to remove such queue records. :param file_path: Queue file full path :param remove_record_idxs: A list of record index those want to remove """ try: with open(file_path, 'r') as f: lines = f.readlines() # NOTE(zhiyan) we need bottom up removing to # keep record index be valid. remove_record_idxs.sort(reverse=True) for record_idx in remove_record_idxs: # Each record has two lines line_no = (record_idx + 1) * 2 - 1 del lines[line_no:line_no + 2] with open(file_path, 'w') as f: f.write(''.join(lines)) os.chmod(file_path, 0o600) except Exception: LOG.error(_("%s file can not be wrote.") % file_path) def add_location(self, image_id, uri, user_context=None): """Adding image location to scrub queue. :param image_id: The opaque image identifier :param uri: The opaque image location uri :param user_context: The user's request context """ if user_context is not None: registry_client = registry.get_registry_client(user_context) else: registry_client = self.registry with lockutils.lock("scrubber-%s" % image_id, lock_file_prefix='glance-', external=True): # NOTE(zhiyan): make sure scrubber does not cleanup # 'pending_delete' images concurrently before the code # get lock and reach here. try: image = registry_client.get_image(image_id) if image['status'] == 'deleted': return except exception.NotFound as e: LOG.error(_("Failed to find image to delete: " "%(e)s"), {'e': e}) return delete_time = time.time() + self.scrub_time file_path = os.path.join(self.scrubber_datadir, str(image_id)) if self.metadata_encryption_key is not None: uri = crypt.urlsafe_encrypt(self.metadata_encryption_key, uri, 64) if os.path.exists(file_path): # Append the uri of location to the queue file with open(file_path, 'a') as f: f.write('\n') f.write('\n'.join([uri, str(int(delete_time))])) else: # NOTE(zhiyan): Protect the file before we write any data. open(file_path, 'w').close() os.chmod(file_path, 0o600) with open(file_path, 'w') as f: f.write('\n'.join([uri, str(int(delete_time))])) os.utime(file_path, (delete_time, delete_time)) def _walk_all_locations(self, remove=False): """Returns a list of image id and location tuple from scrub queue. :param remove: Whether remove location from queue or not after walk :retval a list of image image_id and location tuple from scrub queue """ if not os.path.exists(self.scrubber_datadir): LOG.info(_("%s directory does not exist.") % self.scrubber_datadir) return [] ret = [] for root, dirs, files in os.walk(self.scrubber_datadir): for image_id in files: if not utils.is_uuid_like(image_id): continue with lockutils.lock("scrubber-%s" % image_id, lock_file_prefix='glance-', external=True): file_path = os.path.join(self.scrubber_datadir, image_id) uris, delete_times = self._read_queue_file(file_path) remove_record_idxs = [] skipped = False for (record_idx, delete_time) in enumerate(delete_times): if delete_time > time.time(): skipped = True continue else: ret.append((image_id, uris[record_idx])) remove_record_idxs.append(record_idx) if remove: if skipped: # NOTE(zhiyan): remove location records from # the queue file. self._update_queue_file(file_path, remove_record_idxs) else: utils.safe_remove(file_path) return ret def get_all_locations(self): """Returns a list of image id and location tuple from scrub queue. :retval a list of image id and location tuple from scrub queue """ return self._walk_all_locations() def pop_all_locations(self): """Pop out a list of image id and location tuple from scrub queue. :retval a list of image id and location tuple from scrub queue """ return self._walk_all_locations(remove=True) def has_image(self, image_id): """Returns whether the queue contains an image or not. :param image_id: The opaque image identifier :retval a boolean value to inform including or not """ return os.path.exists(os.path.join(self.scrubber_datadir, str(image_id))) class ScrubDBQueue(ScrubQueue): """Database-based image scrub queue class.""" def __init__(self): super(ScrubDBQueue, self).__init__() self.cleanup_scrubber_time = CONF.cleanup_scrubber_time def add_location(self, image_id, uri, user_context=None): """Adding image location to scrub queue. :param image_id: The opaque image identifier :param uri: The opaque image location uri :param user_context: The user's request context """ raise NotImplementedError def _walk_all_locations(self, remove=False): """Returns a list of image id and location tuple from scrub queue. :param remove: Whether remove location from queue or not after walk :retval a list of image id and location tuple from scrub queue """ filters = {'deleted': True, 'is_public': 'none', 'status': 'pending_delete'} ret = [] for image in self.registry.get_images_detailed(filters=filters): deleted_at = image.get('deleted_at') if not deleted_at: continue # NOTE: Strip off microseconds which may occur after the last '.,' # Example: 2012-07-07T19:14:34.974216 date_str = deleted_at.rsplit('.', 1)[0].rsplit(',', 1)[0] delete_time = calendar.timegm(time.strptime(date_str, "%Y-%m-%dT%H:%M:%S")) if delete_time + self.cleanup_scrubber_time > time.time(): continue ret.extend([(image['id'], location['uri']) for location in image['location_data']]) if remove: self.registry.update_image(image['id'], {'status': 'deleted'}) return ret def get_all_locations(self): """Returns a list of image id and location tuple from scrub queue. :retval a list of image id and location tuple from scrub queue """ return self._walk_all_locations() def pop_all_locations(self): """Pop out a list of image id and location tuple from scrub queue. :retval a list of image id and location tuple from scrub queue """ return self._walk_all_locations(remove=True) def has_image(self, image_id): """Returns whether the queue contains an image or not. :param image_id: The opaque image identifier :retval a boolean value to inform including or not """ try: image = self.registry.get_image(image_id) return image['status'] == 'pending_delete' except exception.NotFound: return False _file_queue = None _db_queue = None def get_scrub_queues(): global _file_queue, _db_queue if not _file_queue: _file_queue = ScrubFileQueue() if not _db_queue: _db_queue = ScrubDBQueue() return (_file_queue, _db_queue) class Daemon(object): def __init__(self, wakeup_time=300, threads=1000): LOG.info(_("Starting Daemon: wakeup_time=%(wakeup_time)s " "threads=%(threads)s"), {'wakeup_time': wakeup_time, 'threads': threads}) self.wakeup_time = wakeup_time self.event = eventlet.event.Event() self.pool = eventlet.greenpool.GreenPool(threads) def start(self, application): self._run(application) def wait(self): try: self.event.wait() except KeyboardInterrupt: msg = _("Daemon Shutdown on KeyboardInterrupt") LOG.info(msg) def _run(self, application): LOG.debug(_("Running application")) self.pool.spawn_n(application.run, self.pool, self.event) eventlet.spawn_after(self.wakeup_time, self._run, application) LOG.debug(_("Next run scheduled in %s seconds") % self.wakeup_time) class Scrubber(object): def __init__(self, store_api): LOG.info(_("Initializing scrubber with configuration: %s") % unicode({'scrubber_datadir': CONF.scrubber_datadir, 'cleanup': CONF.cleanup_scrubber, 'cleanup_time': CONF.cleanup_scrubber_time, 'registry_host': CONF.registry_host, 'registry_port': CONF.registry_port})) utils.safe_mkdirs(CONF.scrubber_datadir) self.store_api = store_api registry.configure_registry_client() registry.configure_registry_admin_creds() self.registry = registry.get_registry_client(context.RequestContext()) (self.file_queue, self.db_queue) = get_scrub_queues() def _get_delete_jobs(self, queue, pop): try: if pop: image_id_uri_list = queue.pop_all_locations() else: image_id_uri_list = queue.get_all_locations() except Exception: LOG.error(_("Can not %s scrub jobs from queue.") % 'pop' if pop else 'get') return None delete_jobs = {} for image_id, image_uri in image_id_uri_list: if image_id not in delete_jobs: delete_jobs[image_id] = [] delete_jobs[image_id].append((image_id, image_uri)) return delete_jobs def run(self, pool, event=None): delete_jobs = self._get_delete_jobs(self.file_queue, True) if delete_jobs: for image_id, jobs in delete_jobs.iteritems(): self._scrub_image(pool, image_id, jobs) if CONF.cleanup_scrubber: self._cleanup(pool) def _scrub_image(self, pool, image_id, delete_jobs): if len(delete_jobs) == 0: return LOG.info(_("Scrubbing image %(id)s from %(count)d locations.") % {'id': image_id, 'count': len(delete_jobs)}) # NOTE(bourke): The starmap must be iterated to do work list(pool.starmap(self._delete_image_from_backend, delete_jobs)) image = self.registry.get_image(image_id) if (image['status'] == 'pending_delete' and not self.file_queue.has_image(image_id)): self.registry.update_image(image_id, {'status': 'deleted'}) def _delete_image_from_backend(self, image_id, uri): if CONF.metadata_encryption_key is not None: uri = crypt.urlsafe_decrypt(CONF.metadata_encryption_key, uri) try: LOG.debug(_("Deleting URI from image %(image_id)s.") % {'image_id': image_id}) # Here we create a request context with credentials to support # delayed delete when using multi-tenant backend storage admin_tenant = CONF.admin_tenant_name auth_token = self.registry.auth_tok admin_context = context.RequestContext(user=CONF.admin_user, tenant=admin_tenant, auth_tok=auth_token) self.store_api.delete_from_backend(admin_context, uri) except Exception: msg = _("Failed to delete URI from image %(image_id)s") LOG.error(msg % {'image_id': image_id}) def _read_cleanup_file(self, file_path): """Reading cleanup to get latest cleanup timestamp. :param file_path: Cleanup status file full path :retval latest cleanup timestamp """ try: if not os.path.exists(file_path): msg = _("%s file is not exists.") % unicode(file_path) raise Exception(msg) atime = int(os.path.getatime(file_path)) mtime = int(os.path.getmtime(file_path)) if atime != mtime: msg = _("%s file contains conflicting cleanup " "timestamp.") % unicode(file_path) raise Exception(msg) return atime except Exception as e: LOG.error(e) return None def _update_cleanup_file(self, file_path, cleanup_time): """Update latest cleanup timestamp to cleanup file. :param file_path: Cleanup status file full path :param cleanup_time: The Latest cleanup timestamp """ try: open(file_path, 'w').close() os.chmod(file_path, 0o600) os.utime(file_path, (cleanup_time, cleanup_time)) except Exception: LOG.error(_("%s file can not be created.") % unicode(file_path)) def _cleanup(self, pool): now = time.time() cleanup_file = os.path.join(CONF.scrubber_datadir, ".cleanup") if not os.path.exists(cleanup_file): self._update_cleanup_file(cleanup_file, now) return last_cleanup_time = self._read_cleanup_file(cleanup_file) cleanup_time = last_cleanup_time + CONF.cleanup_scrubber_time if cleanup_time > now: return LOG.info(_("Getting images deleted before " "%s") % CONF.cleanup_scrubber_time) self._update_cleanup_file(cleanup_file, now) delete_jobs = self._get_delete_jobs(self.db_queue, False) if not delete_jobs: return for image_id, jobs in delete_jobs.iteritems(): with lockutils.lock("scrubber-%s" % image_id, lock_file_prefix='glance-', external=True): if not self.file_queue.has_image(image_id): # NOTE(zhiyan): scrubber should not cleanup this image # since a queue file be created for this 'pending_delete' # image concurrently before the code get lock and # reach here. The checking only be worth if glance-api and # glance-scrubber service be deployed on a same host. self._scrub_image(pool, image_id, jobs) glance-2014.1/glance/registry/0000775000175400017540000000000012323736427017302 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/registry/client/0000775000175400017540000000000012323736427020560 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/registry/client/v2/0000775000175400017540000000000012323736427021107 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/registry/client/v2/api.py0000664000175400017540000000702112323736226022227 0ustar jenkinsjenkins00000000000000# Copyright 2013 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. """ Registry's Client V2 """ import os from oslo.config import cfg from glance.common import exception import glance.openstack.common.log as logging from glance.registry.client.v2 import client LOG = logging.getLogger(__name__) CONF = cfg.CONF _registry_client = 'glance.registry.client' CONF.import_opt('registry_client_protocol', _registry_client) CONF.import_opt('registry_client_key_file', _registry_client) CONF.import_opt('registry_client_cert_file', _registry_client) CONF.import_opt('registry_client_ca_file', _registry_client) CONF.import_opt('registry_client_insecure', _registry_client) CONF.import_opt('registry_client_timeout', _registry_client) CONF.import_opt('use_user_token', _registry_client) CONF.import_opt('admin_user', _registry_client) CONF.import_opt('admin_password', _registry_client) CONF.import_opt('admin_tenant_name', _registry_client) CONF.import_opt('auth_url', _registry_client) CONF.import_opt('auth_strategy', _registry_client) CONF.import_opt('auth_region', _registry_client) _CLIENT_CREDS = None _CLIENT_HOST = None _CLIENT_PORT = None _CLIENT_KWARGS = {} def configure_registry_client(): """ Sets up a registry client for use in registry lookups """ global _CLIENT_KWARGS, _CLIENT_HOST, _CLIENT_PORT try: host, port = CONF.registry_host, CONF.registry_port except cfg.ConfigFileValueError: msg = _("Configuration option was not valid") LOG.error(msg) raise exception.BadRegistryConnectionConfiguration(msg) except IndexError: msg = _("Could not find required configuration option") LOG.error(msg) raise exception.BadRegistryConnectionConfiguration(msg) _CLIENT_HOST = host _CLIENT_PORT = port _CLIENT_KWARGS = { 'use_ssl': CONF.registry_client_protocol.lower() == 'https', 'key_file': CONF.registry_client_key_file, 'cert_file': CONF.registry_client_cert_file, 'ca_file': CONF.registry_client_ca_file, 'insecure': CONF.registry_client_insecure, 'timeout': CONF.registry_client_timeout, } if not CONF.use_user_token: configure_registry_admin_creds() def configure_registry_admin_creds(): global _CLIENT_CREDS 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_CREDS, _CLIENT_KWARGS, _CLIENT_HOST, _CLIENT_PORT kwargs = _CLIENT_KWARGS.copy() if CONF.use_user_token: kwargs['auth_tok'] = cxt.auth_tok if _CLIENT_CREDS: kwargs['creds'] = _CLIENT_CREDS return client.RegistryClient(_CLIENT_HOST, _CLIENT_PORT, **kwargs) glance-2014.1/glance/registry/client/v2/client.py0000664000175400017540000000165312323736226022741 0ustar jenkinsjenkins00000000000000# Copyright 2013 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. """ Simple client class to speak with any RESTful service that implements the Glance Registry API """ from glance.common import rpc import glance.openstack.common.log as logging LOG = logging.getLogger(__name__) class RegistryClient(rpc.RPCClient): """Registry's V2 Client.""" DEFAULT_PORT = 9191 glance-2014.1/glance/registry/client/v2/__init__.py0000664000175400017540000000000012323736226023203 0ustar jenkinsjenkins00000000000000glance-2014.1/glance/registry/client/__init__.py0000664000175400017540000000547012323736226022674 0ustar jenkinsjenkins00000000000000# Copyright 2013 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from oslo.config import cfg registry_client_opts = [ cfg.StrOpt('registry_client_protocol', default='http', help=_('The protocol to use for communication with the ' 'registry server. Either http or https.')), cfg.StrOpt('registry_client_key_file', help=_('The path to the key file to use in SSL connections ' 'to the registry server.')), cfg.StrOpt('registry_client_cert_file', help=_('The path to the cert file to use in SSL connections ' 'to the registry server.')), cfg.StrOpt('registry_client_ca_file', help=_('The path to the certifying authority cert file to ' 'use in SSL connections to the registry server.')), cfg.BoolOpt('registry_client_insecure', default=False, help=_('When using SSL in connections to the registry server, ' 'do not require validation via a certifying ' 'authority.')), cfg.IntOpt('registry_client_timeout', default=600, help=_('The period of time, in seconds, that the API server ' 'will wait for a registry request to complete. A ' 'value of 0 implies no timeout.')), ] registry_client_ctx_opts = [ cfg.BoolOpt('use_user_token', default=True, help=_('Whether to pass through the user token when ' 'making requests to the registry.')), cfg.StrOpt('admin_user', secret=True, help=_('The administrators user name.')), cfg.StrOpt('admin_password', secret=True, help=_('The administrators password.')), cfg.StrOpt('admin_tenant_name', secret=True, help=_('The tenant name of the administrative user.')), cfg.StrOpt('auth_url', help=_('The URL to the keystone service.')), cfg.StrOpt('auth_strategy', default='noauth', help=_('The strategy to use for authentication.')), cfg.StrOpt('auth_region', help=_('The region for the authentication service.')), ] CONF = cfg.CONF CONF.register_opts(registry_client_opts) CONF.register_opts(registry_client_ctx_opts) glance-2014.1/glance/registry/client/v1/0000775000175400017540000000000012323736427021106 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/registry/client/v1/api.py0000664000175400017540000001537312323736226022237 0ustar jenkinsjenkins00000000000000# Copyright 2010-2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ Registry's Client API """ import os from oslo.config import cfg from glance.common import exception from glance.openstack.common import jsonutils import glance.openstack.common.log as logging from glance.registry.client.v1 import client LOG = logging.getLogger(__name__) registry_client_ctx_opts = [ cfg.BoolOpt('send_identity_headers', default=False, help=_("Whether to pass through headers containing user " "and tenant information when making requests to " "the registry. This allows the registry to use the " "context middleware without the keystoneclients' " "auth_token middleware, removing calls to the keystone " "auth service. It is recommended that when using this " "option, secure communication between glance api and " "glance registry is ensured by means other than " "auth_token middleware.")), ] CONF = cfg.CONF CONF.register_opts(registry_client_ctx_opts) _registry_client = 'glance.registry.client' CONF.import_opt('registry_client_protocol', _registry_client) CONF.import_opt('registry_client_key_file', _registry_client) CONF.import_opt('registry_client_cert_file', _registry_client) CONF.import_opt('registry_client_ca_file', _registry_client) CONF.import_opt('registry_client_insecure', _registry_client) CONF.import_opt('registry_client_timeout', _registry_client) CONF.import_opt('use_user_token', _registry_client) CONF.import_opt('admin_user', _registry_client) CONF.import_opt('admin_password', _registry_client) CONF.import_opt('admin_tenant_name', _registry_client) CONF.import_opt('auth_url', _registry_client) CONF.import_opt('auth_strategy', _registry_client) CONF.import_opt('auth_region', _registry_client) CONF.import_opt('metadata_encryption_key', 'glance.common.config') _CLIENT_CREDS = None _CLIENT_HOST = None _CLIENT_PORT = None _CLIENT_KWARGS = {} # AES key used to encrypt 'location' metadata _METADATA_ENCRYPTION_KEY = None def configure_registry_client(): """ Sets up a registry client for use in registry lookups """ global _CLIENT_KWARGS, _CLIENT_HOST, _CLIENT_PORT, _METADATA_ENCRYPTION_KEY try: host, port = CONF.registry_host, CONF.registry_port except cfg.ConfigFileValueError: msg = _("Configuration option was not valid") LOG.error(msg) raise exception.BadRegistryConnectionConfiguration(reason=msg) except IndexError: msg = _("Could not find required configuration option") LOG.error(msg) raise exception.BadRegistryConnectionConfiguration(reason=msg) _CLIENT_HOST = host _CLIENT_PORT = port _METADATA_ENCRYPTION_KEY = CONF.metadata_encryption_key _CLIENT_KWARGS = { 'use_ssl': CONF.registry_client_protocol.lower() == 'https', 'key_file': CONF.registry_client_key_file, 'cert_file': CONF.registry_client_cert_file, 'ca_file': CONF.registry_client_ca_file, 'insecure': CONF.registry_client_insecure, 'timeout': CONF.registry_client_timeout, } if not CONF.use_user_token: configure_registry_admin_creds() def configure_registry_admin_creds(): global _CLIENT_CREDS 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_CREDS, _CLIENT_KWARGS, _CLIENT_HOST, _CLIENT_PORT global _METADATA_ENCRYPTION_KEY kwargs = _CLIENT_KWARGS.copy() if CONF.use_user_token: kwargs['auth_tok'] = cxt.auth_tok if _CLIENT_CREDS: kwargs['creds'] = _CLIENT_CREDS if CONF.send_identity_headers: identity_headers = { 'X-User-Id': cxt.user, 'X-Tenant-Id': cxt.tenant, 'X-Roles': ','.join(cxt.roles), 'X-Identity-Status': 'Confirmed', 'X-Service-Catalog': jsonutils.dumps(cxt.service_catalog), } kwargs['identity_headers'] = identity_headers return client.RegistryClient(_CLIENT_HOST, _CLIENT_PORT, _METADATA_ENCRYPTION_KEY, **kwargs) def get_images_list(context, **kwargs): c = get_registry_client(context) return c.get_images(**kwargs) def get_images_detail(context, **kwargs): c = get_registry_client(context) return c.get_images_detailed(**kwargs) def get_image_metadata(context, image_id): c = get_registry_client(context) return c.get_image(image_id) def add_image_metadata(context, image_meta): LOG.debug(_("Adding image metadata...")) c = get_registry_client(context) return c.add_image(image_meta) def update_image_metadata(context, image_id, image_meta, purge_props=False, from_state=None): LOG.debug(_("Updating image metadata for image %s..."), image_id) c = get_registry_client(context) return c.update_image(image_id, image_meta, purge_props=purge_props, from_state=from_state) def delete_image_metadata(context, image_id): LOG.debug(_("Deleting image metadata for image %s..."), image_id) c = get_registry_client(context) return c.delete_image(image_id) def get_image_members(context, image_id): c = get_registry_client(context) return c.get_image_members(image_id) def get_member_images(context, member_id): c = get_registry_client(context) return c.get_member_images(member_id) def replace_members(context, image_id, member_data): c = get_registry_client(context) return c.replace_members(image_id, member_data) def add_member(context, image_id, member_id, can_share=None): c = get_registry_client(context) return c.add_member(image_id, member_id, can_share=can_share) def delete_member(context, image_id, member_id): c = get_registry_client(context) return c.delete_member(image_id, member_id) glance-2014.1/glance/registry/client/v1/client.py0000664000175400017540000002432312323736230022732 0ustar jenkinsjenkins00000000000000# Copyright 2013 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ Simple client class to speak with any RESTful service that implements the Glance Registry API """ from glance.common.client import BaseClient from glance.common import crypt from glance.openstack.common import jsonutils import glance.openstack.common.log as logging from glance.registry.api.v1 import images LOG = logging.getLogger(__name__) class RegistryClient(BaseClient): """A client for the Registry image metadata service.""" DEFAULT_PORT = 9191 def __init__(self, host=None, port=None, metadata_encryption_key=None, identity_headers=None, **kwargs): """ :param metadata_encryption_key: Key used to encrypt 'location' metadata """ self.metadata_encryption_key = metadata_encryption_key # 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 self.identity_headers = identity_headers BaseClient.__init__(self, host, port, configure_via_auth=False, **kwargs) def decrypt_metadata(self, image_metadata): if self.metadata_encryption_key is not None: if image_metadata.get('location'): location = crypt.urlsafe_decrypt(self.metadata_encryption_key, image_metadata['location']) image_metadata['location'] = location if image_metadata.get('location_data'): ld = [] for loc in image_metadata['location_data']: url = crypt.urlsafe_decrypt(self.metadata_encryption_key, loc['url']) ld.append({'url': url, 'metadata': loc['metadata']}) image_metadata['location_data'] = ld return image_metadata def encrypt_metadata(self, image_metadata): if self.metadata_encryption_key is not None: location_url = image_metadata.get('location') if location_url: location = crypt.urlsafe_encrypt(self.metadata_encryption_key, location_url, 64) image_metadata['location'] = location if image_metadata.get('location_data'): ld = [] for loc in image_metadata['location_data']: if loc['url'] == location_url: url = location else: url = crypt.urlsafe_encrypt( self.metadata_encryption_key, loc['url'], 64) ld.append({'url': url, 'metadata': loc['metadata']}) image_metadata['location_data'] = ld return image_metadata def get_images(self, **kwargs): """ Returns a list of image id/name mappings from Registry :param filters: dict of keys & expected values to filter results :param marker: image id after which to start page :param limit: max number of images to return :param sort_key: results will be ordered by this image attribute :param sort_dir: direction in which to to order results (asc, desc) """ params = self._extract_params(kwargs, images.SUPPORTED_PARAMS) res = self.do_request("GET", "/images", params=params) image_list = jsonutils.loads(res.read())['images'] for image in image_list: image = self.decrypt_metadata(image) return image_list def do_request(self, method, action, **kwargs): try: kwargs['headers'] = kwargs.get('headers', {}) kwargs['headers'].update(self.identity_headers or {}) res = super(RegistryClient, self).do_request(method, action, **kwargs) status = res.status request_id = res.getheader('x-openstack-request-id') msg = (_("Registry request %(method)s %(action)s HTTP %(status)s" " request id %(request_id)s") % {'method': method, 'action': action, 'status': status, 'request_id': request_id}) LOG.debug(msg) except Exception as exc: exc_name = exc.__class__.__name__ LOG.info(_("Registry client request %(method)s %(action)s " "raised %(exc_name)s"), {'method': method, 'action': action, 'exc_name': exc_name}) raise return res def get_images_detailed(self, **kwargs): """ Returns a list of detailed image data mappings from Registry :param filters: dict of keys & expected values to filter results :param marker: image id after which to start page :param limit: max number of images to return :param sort_key: results will be ordered by this image attribute :param sort_dir: direction in which to to order results (asc, desc) """ params = self._extract_params(kwargs, images.SUPPORTED_PARAMS) res = self.do_request("GET", "/images/detail", params=params) image_list = jsonutils.loads(res.read())['images'] for image in image_list: image = self.decrypt_metadata(image) return image_list def get_image(self, image_id): """Returns a mapping of image metadata from Registry.""" res = self.do_request("GET", "/images/%s" % image_id) data = jsonutils.loads(res.read())['image'] return self.decrypt_metadata(data) def add_image(self, image_metadata): """ Tells registry about an image's metadata """ headers = { 'Content-Type': 'application/json', } if 'image' not in image_metadata: image_metadata = dict(image=image_metadata) encrypted_metadata = self.encrypt_metadata(image_metadata['image']) image_metadata['image'] = encrypted_metadata body = jsonutils.dumps(image_metadata) res = self.do_request("POST", "/images", body=body, headers=headers) # Registry returns a JSONified dict(image=image_info) data = jsonutils.loads(res.read()) image = data['image'] return self.decrypt_metadata(image) def update_image(self, image_id, image_metadata, purge_props=False, from_state=None): """ Updates Registry's information about an image """ if 'image' not in image_metadata: image_metadata = dict(image=image_metadata) encrypted_metadata = self.encrypt_metadata(image_metadata['image']) image_metadata['image'] = encrypted_metadata image_metadata['from_state'] = from_state body = jsonutils.dumps(image_metadata) headers = { 'Content-Type': 'application/json', } if purge_props: headers["X-Glance-Registry-Purge-Props"] = "true" res = self.do_request("PUT", "/images/%s" % image_id, body=body, headers=headers) data = jsonutils.loads(res.read()) image = data['image'] return self.decrypt_metadata(image) def delete_image(self, image_id): """ Deletes Registry's information about an image """ res = self.do_request("DELETE", "/images/%s" % image_id) data = jsonutils.loads(res.read()) image = data['image'] return image def get_image_members(self, image_id): """Return a list of membership associations from Registry.""" res = self.do_request("GET", "/images/%s/members" % image_id) data = jsonutils.loads(res.read())['members'] return data def get_member_images(self, member_id): """Return a list of membership associations from Registry.""" res = self.do_request("GET", "/shared-images/%s" % member_id) data = jsonutils.loads(res.read())['shared_images'] return data def replace_members(self, image_id, member_data): """Replace registry's information about image membership.""" if isinstance(member_data, (list, tuple)): member_data = dict(memberships=list(member_data)) elif (isinstance(member_data, dict) and 'memberships' not in member_data): member_data = dict(memberships=[member_data]) body = jsonutils.dumps(member_data) headers = {'Content-Type': 'application/json', } res = self.do_request("PUT", "/images/%s/members" % image_id, body=body, headers=headers) return self.get_status_code(res) == 204 def add_member(self, image_id, member_id, can_share=None): """Add to registry's information about image membership.""" body = None headers = {} # Build up a body if can_share is specified if can_share is not None: body = jsonutils.dumps(dict(member=dict(can_share=can_share))) headers['Content-Type'] = 'application/json' url = "/images/%s/members/%s" % (image_id, member_id) res = self.do_request("PUT", url, body=body, headers=headers) return self.get_status_code(res) == 204 def delete_member(self, image_id, member_id): """Delete registry's information about image membership.""" res = self.do_request("DELETE", "/images/%s/members/%s" % (image_id, member_id)) return self.get_status_code(res) == 204 glance-2014.1/glance/registry/client/v1/__init__.py0000664000175400017540000000000012323736226023202 0ustar jenkinsjenkins00000000000000glance-2014.1/glance/registry/api/0000775000175400017540000000000012323736427020053 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/registry/api/v2/0000775000175400017540000000000012323736427020402 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/registry/api/v2/rpc.py0000664000175400017540000000321412323736226021535 0ustar jenkinsjenkins00000000000000# Copyright 2013 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. """ RPC Controller """ from oslo.config import cfg from glance.common import rpc from glance.common import wsgi import glance.db import glance.openstack.common.log as logging LOG = logging.getLogger(__name__) CONF = cfg.CONF class Controller(rpc.Controller): def __init__(self, raise_exc=False): super(Controller, self).__init__(raise_exc) # NOTE(flaper87): Avoid using registry's db # driver for the registry service. It would # end up in an infinite loop. if CONF.data_api == "glance.db.registry.api": msg = _("Registry service can't use %s") % CONF.data_api raise RuntimeError(msg) # NOTE(flaper87): Register the # db_api as a resource to expose. db_api = glance.db.get_api() self.register(glance.db.unwrap(db_api)) def create_resource(): """Images resource factory method.""" deserializer = rpc.RPCJSONDeserializer() serializer = rpc.RPCJSONSerializer() return wsgi.Resource(Controller(), deserializer, serializer) glance-2014.1/glance/registry/api/v2/__init__.py0000664000175400017540000000216512323736226022514 0ustar jenkinsjenkins00000000000000# Copyright 2013 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. from glance.common import wsgi from glance.registry.api.v2 import rpc def init(mapper): rpc_resource = rpc.create_resource() mapper.connect("/rpc", controller=rpc_resource, conditions=dict(method=["POST"]), action="__call__") class API(wsgi.Router): """WSGI entry point for all Registry requests.""" def __init__(self, mapper): mapper = mapper or wsgi.APIMapper() init(mapper) super(API, self).__init__(mapper) glance-2014.1/glance/registry/api/__init__.py0000664000175400017540000000235012323736226022161 0ustar jenkinsjenkins00000000000000# Copyright 2014 Hewlett-Packard Development Company, L.P. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from oslo.config import cfg from glance.common import wsgi from glance.registry.api import v1 from glance.registry.api import v2 CONF = cfg.CONF CONF.import_opt('enable_v1_registry', 'glance.common.config') CONF.import_opt('enable_v2_registry', 'glance.common.config') class API(wsgi.Router): """WSGI entry point for all Registry requests.""" def __init__(self, mapper): mapper = mapper or wsgi.APIMapper() if CONF.enable_v1_registry: v1.init(mapper) if CONF.enable_v2_registry: v2.init(mapper) super(API, self).__init__(mapper) glance-2014.1/glance/registry/api/v1/0000775000175400017540000000000012323736427020401 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/registry/api/v1/images.py0000664000175400017540000004627012323736226022226 0ustar jenkinsjenkins00000000000000# Copyright 2010-2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ Reference implementation registry server WSGI controller """ from oslo.config import cfg from webob import exc from glance.common import exception from glance.common import utils from glance.common import wsgi import glance.db import glance.openstack.common.log as logging from glance.openstack.common import strutils from glance.openstack.common import timeutils LOG = logging.getLogger(__name__) CONF = cfg.CONF DISPLAY_FIELDS_IN_INDEX = ['id', 'name', 'size', 'disk_format', 'container_format', 'checksum'] SUPPORTED_FILTERS = ['name', 'status', 'container_format', 'disk_format', 'min_ram', 'min_disk', 'size_min', 'size_max', 'changes-since', 'protected'] SUPPORTED_SORT_KEYS = ('name', 'status', 'container_format', 'disk_format', 'size', 'id', 'created_at', 'updated_at') SUPPORTED_SORT_DIRS = ('asc', 'desc') SUPPORTED_PARAMS = ('limit', 'marker', 'sort_key', 'sort_dir') def _normalize_image_location_for_db(image_data): """ This function takes the legacy locations field and the newly added location_data field from the image_data values dictionary which flows over the wire between the registry and API servers and converts it into the location_data format only which is then consumable by the Image object. :param image_data: a dict of values representing information in the image :return: a new image data dict """ if 'locations' not in image_data and 'location_data' not in image_data: image_data['locations'] = None return image_data locations = image_data.pop('locations', []) location_data = image_data.pop('location_data', []) location_data_dict = {} for l in locations: location_data_dict[l] = {} for l in location_data: location_data_dict[l['url']] = l['metadata'] # NOTE(jbresnah) preserve original order. tests assume original order, # should that be defined functionality ordered_keys = locations[:] for ld in location_data: if ld['url'] not in ordered_keys: ordered_keys.append(ld['url']) location_data = [{'url': l, 'metadata': location_data_dict[l]} for l in ordered_keys] image_data['locations'] = location_data return image_data class Controller(object): def __init__(self): self.db_api = glance.db.get_api() def _get_images(self, context, filters, **params): """Get images, wrapping in exception if necessary.""" # NOTE(markwash): for backwards compatibility, is_public=True for # admins actually means "treat me as if I'm not an admin and show me # all my images" if context.is_admin and params.get('is_public') is True: params['admin_as_user'] = True del params['is_public'] try: return self.db_api.image_get_all(context, filters=filters, **params) except exception.NotFound: LOG.info(_("Invalid marker. Image %(id)s could not be " "found.") % {'id': params.get('marker')}) msg = _("Invalid marker. Image could not be found.") raise exc.HTTPBadRequest(explanation=msg) except exception.Forbidden: LOG.info(_("Access denied to image %(id)s but returning " "'not found'") % {'id': params.get('marker')}) msg = _("Invalid marker. Image could not be found.") raise exc.HTTPBadRequest(explanation=msg) except Exception: LOG.exception(_("Unable to get images")) raise def index(self, req): """Return a basic filtered list of public, non-deleted images :param req: the Request object coming from the wsgi layer :retval a mapping of the following form:: dict(images=[image_list]) Where image_list is a sequence of mappings:: { 'id': , 'name': , 'size': , 'disk_format': , 'container_format': , 'checksum': } """ params = self._get_query_params(req) images = self._get_images(req.context, **params) results = [] for image in images: result = {} for field in DISPLAY_FIELDS_IN_INDEX: result[field] = image[field] results.append(result) LOG.info(_("Returning image list")) return dict(images=results) def detail(self, req): """Return a filtered list of public, non-deleted images in detail :param req: the Request object coming from the wsgi layer :retval a mapping of the following form:: dict(images=[image_list]) Where image_list is a sequence of mappings containing all image model fields. """ params = self._get_query_params(req) images = self._get_images(req.context, **params) image_dicts = [make_image_dict(i) for i in images] LOG.info(_("Returning detailed image list")) return dict(images=image_dicts) def _get_query_params(self, req): """Extract necessary query parameters from http request. :param req: the Request object coming from the wsgi layer :retval dictionary of filters to apply to list of images """ params = { 'filters': self._get_filters(req), 'limit': self._get_limit(req), 'sort_key': self._get_sort_key(req), 'sort_dir': self._get_sort_dir(req), 'marker': self._get_marker(req), } if req.context.is_admin: # Only admin gets to look for non-public images params['is_public'] = self._get_is_public(req) for key, value in params.items(): if value is None: del params[key] # Fix for LP Bug #1132294 # Ensure all shared images are returned in v1 params['member_status'] = 'all' return params def _get_filters(self, req): """Return a dictionary of query param filters from the request :param req: the Request object coming from the wsgi layer :retval a dict of key/value filters """ filters = {} properties = {} for param in req.params: if param in SUPPORTED_FILTERS: filters[param] = req.params.get(param) if param.startswith('property-'): _param = param[9:] properties[_param] = req.params.get(param) if 'changes-since' in filters: isotime = filters['changes-since'] try: filters['changes-since'] = timeutils.parse_isotime(isotime) except ValueError: raise exc.HTTPBadRequest(_("Unrecognized changes-since value")) if 'protected' in filters: value = self._get_bool(filters['protected']) if value is None: raise exc.HTTPBadRequest(_("protected must be True, or " "False")) filters['protected'] = value # only allow admins to filter on 'deleted' if req.context.is_admin: deleted_filter = self._parse_deleted_filter(req) if deleted_filter is not None: filters['deleted'] = deleted_filter elif 'changes-since' not in filters: filters['deleted'] = False elif 'changes-since' not in filters: filters['deleted'] = False if properties: filters['properties'] = properties return filters def _get_limit(self, req): """Parse a limit query param into something usable.""" try: limit = int(req.params.get('limit', CONF.limit_param_default)) except ValueError: raise exc.HTTPBadRequest(_("limit param must be an integer")) if limit < 0: raise exc.HTTPBadRequest(_("limit param must be positive")) return min(CONF.api_limit_max, limit) def _get_marker(self, req): """Parse a marker query param into something usable.""" marker = req.params.get('marker', None) if marker and not utils.is_uuid_like(marker): msg = _('Invalid marker format') raise exc.HTTPBadRequest(explanation=msg) return marker def _get_sort_key(self, req): """Parse a sort key query param from the request object.""" sort_key = req.params.get('sort_key', None) if sort_key is not None and sort_key not in SUPPORTED_SORT_KEYS: _keys = ', '.join(SUPPORTED_SORT_KEYS) msg = _("Unsupported sort_key. Acceptable values: %s") % (_keys,) raise exc.HTTPBadRequest(explanation=msg) return sort_key def _get_sort_dir(self, req): """Parse a sort direction query param from the request object.""" sort_dir = req.params.get('sort_dir', None) if sort_dir is not None and sort_dir not in SUPPORTED_SORT_DIRS: _keys = ', '.join(SUPPORTED_SORT_DIRS) msg = _("Unsupported sort_dir. Acceptable values: %s") % (_keys,) raise exc.HTTPBadRequest(explanation=msg) return sort_dir def _get_bool(self, value): value = value.lower() if value == 'true' or value == '1': return True elif value == 'false' or value == '0': return False return None def _get_is_public(self, req): """Parse is_public into something usable.""" is_public = req.params.get('is_public', None) if is_public is None: # NOTE(vish): This preserves the default value of showing only # public images. return True elif is_public.lower() == 'none': return None value = self._get_bool(is_public) if value is None: raise exc.HTTPBadRequest(_("is_public must be None, True, or " "False")) return value def _parse_deleted_filter(self, req): """Parse deleted into something usable.""" deleted = req.params.get('deleted') if deleted is None: return None return strutils.bool_from_string(deleted) def show(self, req, id): """Return data about the given image id.""" try: image = self.db_api.image_get(req.context, id) msg = _("Successfully retrieved image %(id)s") LOG.info(msg % {'id': id}) except exception.NotFound: msg = _("Image %(id)s not found") LOG.info(msg % {'id': id}) raise exc.HTTPNotFound() except exception.Forbidden: # If it's private and doesn't belong to them, don't let on # that it exists msg = _("Access denied to image %(id)s but returning 'not found'") LOG.info(msg % {'id': id}) raise exc.HTTPNotFound() except Exception: LOG.exception(_("Unable to show image %s"), id) raise return dict(image=make_image_dict(image)) @utils.mutating def delete(self, req, id): """Deletes an existing image with the registry. :param req: wsgi Request object :param id: The opaque internal identifier for the image :retval Returns 200 if delete was successful, a fault if not. On success, the body contains the deleted image information as a mapping. """ try: deleted_image = self.db_api.image_destroy(req.context, id) msg = _("Successfully deleted image %(id)s") LOG.info(msg % {'id': id}) return dict(image=make_image_dict(deleted_image)) except exception.ForbiddenPublicImage: msg = _("Delete denied for public image %(id)s") LOG.info(msg % {'id': id}) raise exc.HTTPForbidden() except exception.Forbidden: # If it's private and doesn't belong to them, don't let on # that it exists msg = _("Access denied to image %(id)s but returning 'not found'") LOG.info(msg % {'id': id}) return exc.HTTPNotFound() except exception.NotFound: msg = _("Image %(id)s not found") LOG.info(msg % {'id': id}) return exc.HTTPNotFound() except Exception: LOG.exception(_("Unable to delete image %s"), id) raise @utils.mutating def create(self, req, body): """Registers a new image with the registry. :param req: wsgi Request object :param body: Dictionary of information about the image :retval Returns the newly-created image information as a mapping, which will include the newly-created image's internal id in the 'id' field """ image_data = body['image'] # Ensure the image has a status set image_data.setdefault('status', 'active') # Set up the image owner if not req.context.is_admin or 'owner' not in image_data: image_data['owner'] = req.context.owner image_id = image_data.get('id') if image_id and not utils.is_uuid_like(image_id): msg = _("Rejecting image creation request for invalid image " "id '%(bad_id)s'") LOG.info(msg % {'bad_id': image_id}) msg = _("Invalid image id format") return exc.HTTPBadRequest(explanation=msg) if 'location' in image_data: image_data['locations'] = [image_data.pop('location')] try: image_data = _normalize_image_location_for_db(image_data) image_data = self.db_api.image_create(req.context, image_data) image_data = dict(image=make_image_dict(image_data)) msg = _("Successfully created image %(id)s") % image_data['image'] LOG.info(msg) return image_data except exception.Duplicate: msg = _("Image with identifier %s already exists!") % image_id LOG.error(msg) return exc.HTTPConflict(msg) except exception.Invalid as e: msg = (_("Failed to add image metadata. " "Got error: %(e)s") % {'e': e}) LOG.error(msg) return exc.HTTPBadRequest(msg) except Exception: LOG.exception(_("Unable to create image %s"), image_id) raise @utils.mutating def update(self, req, id, body): """Updates an existing image with the registry. :param req: wsgi Request object :param body: Dictionary of information about the image :param id: The opaque internal identifier for the image :retval Returns the updated image information as a mapping, """ image_data = body['image'] from_state = body.get('from_state', None) # Prohibit modification of 'owner' if not req.context.is_admin and 'owner' in image_data: del image_data['owner'] if 'location' in image_data: image_data['locations'] = [image_data.pop('location')] purge_props = req.headers.get("X-Glance-Registry-Purge-Props", "false") try: LOG.debug(_("Updating image %(id)s with metadata: " "%(image_data)r"), {'id': id, 'image_data': image_data}) image_data = _normalize_image_location_for_db(image_data) if purge_props == "true": purge_props = True else: purge_props = False updated_image = self.db_api.image_update(req.context, id, image_data, purge_props=purge_props, from_state=from_state) msg = _("Updating metadata for image %(id)s") LOG.info(msg % {'id': id}) return dict(image=make_image_dict(updated_image)) except exception.Invalid as e: msg = (_("Failed to update image metadata. " "Got error: %(e)s") % {'e': e}) LOG.error(msg) return exc.HTTPBadRequest(msg) except exception.NotFound: msg = _("Image %(id)s not found") LOG.info(msg % {'id': id}) raise exc.HTTPNotFound(body='Image not found', request=req, content_type='text/plain') except exception.ForbiddenPublicImage: msg = _("Update denied for public image %(id)s") LOG.info(msg % {'id': id}) raise exc.HTTPForbidden() except exception.Forbidden: # If it's private and doesn't belong to them, don't let on # that it exists msg = _("Access denied to image %(id)s but returning 'not found'") LOG.info(msg % {'id': id}) raise exc.HTTPNotFound(body='Image not found', request=req, content_type='text/plain') except exception.Conflict as e: LOG.info(unicode(e)) raise exc.HTTPConflict(body='Image operation conflicts', request=req, content_type='text/plain') except Exception: LOG.exception(_("Unable to update image %s"), id) raise def _limit_locations(image): locations = image.pop('locations', []) try: image['location'] = locations[0]['url'] except IndexError: image['location'] = None image['location_data'] = locations def make_image_dict(image): """Create a dict representation of an image which we can use to serialize the image. """ def _fetch_attrs(d, attrs): return dict([(a, d[a]) for a in attrs if a in d.keys()]) # TODO(sirp): should this be a dict, or a list of dicts? # A plain dict is more convenient, but list of dicts would provide # access to created_at, etc properties = dict((p['name'], p['value']) for p in image['properties'] if not p['deleted']) image_dict = _fetch_attrs(image, glance.db.IMAGE_ATTRS) image_dict['properties'] = properties _limit_locations(image_dict) return image_dict def create_resource(): """Images resource factory method.""" deserializer = wsgi.JSONRequestDeserializer() serializer = wsgi.JSONResponseSerializer() return wsgi.Resource(Controller(), deserializer, serializer) glance-2014.1/glance/registry/api/v1/members.py0000664000175400017540000003265512323736226022415 0ustar jenkinsjenkins00000000000000# Copyright 2010-2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import webob.exc from glance.common import exception from glance.common import utils from glance.common import wsgi import glance.db import glance.openstack.common.log as logging LOG = logging.getLogger(__name__) class Controller(object): def _check_can_access_image_members(self, context): if context.owner is None and not context.is_admin: raise webob.exc.HTTPUnauthorized(_("No authenticated user")) def __init__(self): self.db_api = glance.db.get_api() def is_image_sharable(self, context, image): """Return True if the image can be shared to others in this context.""" # Is admin == image sharable if context.is_admin: return True # Only allow sharing if we have an owner if context.owner is None: return False # If we own the image, we can share it if context.owner == image['owner']: return True members = self.db_api.image_member_find(context, image_id=image['id'], member=context.owner) if members: return members[0]['can_share'] return False def index(self, req, image_id): """ Get the members of an image. """ try: self.db_api.image_get(req.context, image_id) except exception.NotFound: msg = _("Image %(id)s not found") % {'id': image_id} LOG.info(msg) raise webob.exc.HTTPNotFound(msg) except exception.Forbidden: # If it's private and doesn't belong to them, don't let on # that it exists msg = _("Access denied to image %(id)s but returning 'not found'") LOG.info(msg % {'id': image_id}) raise webob.exc.HTTPNotFound() members = self.db_api.image_member_find(req.context, image_id=image_id) msg = _("Returning member list for image %(id)s") LOG.info(msg % {'id': image_id}) return dict(members=make_member_list(members, member_id='member', can_share='can_share')) @utils.mutating def update_all(self, req, image_id, body): """ Replaces the members of the image with those specified in the body. The body is a dict with the following format:: {"memberships": [ {"member_id": , ["can_share": [True|False]]}, ... ]} """ self._check_can_access_image_members(req.context) # Make sure the image exists try: image = self.db_api.image_get(req.context, image_id) except exception.NotFound: msg = _("Image %(id)s not found") % {'id': image_id} LOG.info(msg) raise webob.exc.HTTPNotFound(msg) except exception.Forbidden: # If it's private and doesn't belong to them, don't let on # that it exists msg = _("Access denied to image %(id)s but returning 'not found'") LOG.info(msg % {'id': image_id}) raise webob.exc.HTTPNotFound() # Can they manipulate the membership? if not self.is_image_sharable(req.context, image): msg = _("User lacks permission to share image %(id)s") LOG.info(msg % {'id': image_id}) msg = _("No permission to share that image") raise webob.exc.HTTPForbidden(msg) # Get the membership list try: memb_list = body['memberships'] except Exception as e: # Malformed entity... msg = _("Invalid membership association specified for " "image %(id)s") LOG.info(msg % {'id': image_id}) msg = _("Invalid membership association: %s") % e raise webob.exc.HTTPBadRequest(explanation=msg) add = [] existing = {} # Walk through the incoming memberships for memb in memb_list: try: datum = dict(image_id=image['id'], member=memb['member_id'], can_share=None) except Exception as e: # Malformed entity... msg = _("Invalid membership association specified for " "image %(id)s") LOG.info(msg % {'id': image_id}) msg = _("Invalid membership association: %s") % e raise webob.exc.HTTPBadRequest(explanation=msg) # Figure out what can_share should be if 'can_share' in memb: datum['can_share'] = bool(memb['can_share']) # Try to find the corresponding membership members = self.db_api.image_member_find(req.context, image_id=datum['image_id'], member=datum['member']) try: member = members[0] except IndexError: # Default can_share datum['can_share'] = bool(datum['can_share']) add.append(datum) else: # Are we overriding can_share? if datum['can_share'] is None: datum['can_share'] = members[0]['can_share'] existing[member['id']] = { 'values': datum, 'membership': member, } # We now have a filtered list of memberships to add and # memberships to modify. Let's start by walking through all # the existing image memberships... existing_members = self.db_api.image_member_find(req.context, image_id=image['id']) for member in existing_members: if member['id'] in existing: # Just update the membership in place update = existing[member['id']]['values'] self.db_api.image_member_update(req.context, member['id'], update) else: # Outdated one; needs to be deleted self.db_api.image_member_delete(req.context, member['id']) # Now add the non-existent ones for memb in add: self.db_api.image_member_create(req.context, memb) # Make an appropriate result msg = _("Successfully updated memberships for image %(id)s") LOG.info(msg % {'id': image_id}) return webob.exc.HTTPNoContent() @utils.mutating def update(self, req, image_id, id, body=None): """ Adds a membership to the image, or updates an existing one. If a body is present, it is a dict with the following format:: {"member": { "can_share": [True|False] }} If "can_share" is provided, the member's ability to share is set accordingly. If it is not provided, existing memberships remain unchanged and new memberships default to False. """ self._check_can_access_image_members(req.context) # Make sure the image exists try: image = self.db_api.image_get(req.context, image_id) except exception.NotFound: msg = _("Image %(id)s not found") % {'id': image_id} LOG.info(msg) raise webob.exc.HTTPNotFound(msg) except exception.Forbidden: # If it's private and doesn't belong to them, don't let on # that it exists msg = _("Access denied to image %(id)s but returning 'not found'") LOG.info(msg % {'id': image_id}) raise webob.exc.HTTPNotFound() # Can they manipulate the membership? if not self.is_image_sharable(req.context, image): msg = _("User lacks permission to share image %(id)s") LOG.info(msg % {'id': image_id}) msg = _("No permission to share that image") raise webob.exc.HTTPForbidden(msg) # Determine the applicable can_share value can_share = None if body: try: can_share = bool(body['member']['can_share']) except Exception as e: # Malformed entity... msg = _("Invalid membership association specified for " "image %(id)s") LOG.info(msg % {'id': image_id}) msg = _("Invalid membership association: %s") % e raise webob.exc.HTTPBadRequest(explanation=msg) # Look up an existing membership... members = self.db_api.image_member_find(req.context, image_id=image_id, member=id) if members: if can_share is not None: values = dict(can_share=can_share) self.db_api.image_member_update(req.context, members[0]['id'], values) else: values = dict(image_id=image['id'], member=id, can_share=bool(can_share)) self.db_api.image_member_create(req.context, values) msg = _("Successfully updated a membership for image %(id)s") LOG.info(msg % {'id': image_id}) return webob.exc.HTTPNoContent() @utils.mutating def delete(self, req, image_id, id): """ Removes a membership from the image. """ self._check_can_access_image_members(req.context) # Make sure the image exists try: image = self.db_api.image_get(req.context, image_id) except exception.NotFound: msg = _("Image %(id)s not found") % {'id': image_id} LOG.info(msg) raise webob.exc.HTTPNotFound(msg) except exception.Forbidden: # If it's private and doesn't belong to them, don't let on # that it exists msg = _("Access denied to image %(id)s but returning 'not found'") LOG.info(msg % {'id': image_id}) raise webob.exc.HTTPNotFound() # Can they manipulate the membership? if not self.is_image_sharable(req.context, image): msg = _("User lacks permission to share image %(id)s") LOG.info(msg % {'id': image_id}) msg = _("No permission to share that image") raise webob.exc.HTTPForbidden(msg) # Look up an existing membership members = self.db_api.image_member_find(req.context, image_id=image_id, member=id) if members: self.db_api.image_member_delete(req.context, members[0]['id']) else: msg = (_("%(id)s is not a member of image %(image_id)s") % {'id': id, 'image_id': image_id}) LOG.debug(msg) msg = _("Membership could not be found.") raise webob.exc.HTTPNotFound(explanation=msg) # Make an appropriate result msg = _("Successfully deleted a membership from image %(id)s") LOG.info(msg % {'id': image_id}) return webob.exc.HTTPNoContent() def index_shared_images(self, req, id): """ Retrieves images shared with the given member. """ try: members = self.db_api.image_member_find(req.context, member=id) except exception.NotFound: msg = _("Member %(id)s not found") LOG.info(msg % {'id': id}) msg = _("Membership could not be found.") raise webob.exc.HTTPBadRequest(explanation=msg) msg = _("Returning list of images shared with member %(id)s") LOG.info(msg % {'id': id}) return dict(shared_images=make_member_list(members, image_id='image_id', can_share='can_share')) def make_member_list(members, **attr_map): """ Create a dict representation of a list of members which we can use to serialize the members list. Keyword arguments map the names of optional attributes to include to the database attribute. """ def _fetch_memb(memb, attr_map): return dict([(k, memb[v]) for k, v in attr_map.items() if v in memb.keys()]) # Return the list of members with the given attribute mapping return [_fetch_memb(memb, attr_map) for memb in members] def create_resource(): """Image members resource factory method.""" deserializer = wsgi.JSONRequestDeserializer() serializer = wsgi.JSONResponseSerializer() return wsgi.Resource(Controller(), deserializer, serializer) glance-2014.1/glance/registry/api/v1/__init__.py0000664000175400017540000000716612323736226022521 0ustar jenkinsjenkins00000000000000# Copyright 2010-2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from glance.common import wsgi from glance.registry.api.v1 import images from glance.registry.api.v1 import members def init(mapper): images_resource = images.create_resource() mapper.connect("/", controller=images_resource, action="index") mapper.connect("/images", controller=images_resource, action="index", conditions={'method': ['GET']}) mapper.connect("/images", controller=images_resource, action="create", conditions={'method': ['POST']}) mapper.connect("/images/detail", controller=images_resource, action="detail", conditions={'method': ['GET']}) mapper.connect("/images/{id}", controller=images_resource, action="show", conditions=dict(method=["GET"])) mapper.connect("/images/{id}", controller=images_resource, action="update", conditions=dict(method=["PUT"])) mapper.connect("/images/{id}", controller=images_resource, action="delete", conditions=dict(method=["DELETE"])) members_resource = members.create_resource() mapper.connect("/images/{image_id}/members", controller=members_resource, action="index", conditions={'method': ['GET']}) mapper.connect("/images/{image_id}/members", controller=members_resource, action="create", conditions={'method': ['POST']}) mapper.connect("/images/{image_id}/members", controller=members_resource, action="update_all", conditions=dict(method=["PUT"])) mapper.connect("/images/{image_id}/members/{id}", controller=members_resource, action="show", conditions={'method': ['GET']}) mapper.connect("/images/{image_id}/members/{id}", controller=members_resource, action="update", conditions={'method': ['PUT']}) mapper.connect("/images/{image_id}/members/{id}", controller=members_resource, action="delete", conditions={'method': ['DELETE']}) mapper.connect("/shared-images/{id}", controller=members_resource, action="index_shared_images") class API(wsgi.Router): """WSGI entry point for all Registry requests.""" def __init__(self, mapper): mapper = mapper or wsgi.APIMapper() init(mapper) super(API, self).__init__(mapper) glance-2014.1/glance/registry/__init__.py0000664000175400017540000000175412323736226021417 0ustar jenkinsjenkins00000000000000# Copyright 2010-2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ Registry API """ from oslo.config import cfg registry_addr_opts = [ cfg.StrOpt('registry_host', default='0.0.0.0', help=_('Address to find the registry server.')), cfg.IntOpt('registry_port', default=9191, help=_('Port the registry server is listening on.')), ] CONF = cfg.CONF CONF.register_opts(registry_addr_opts) glance-2014.1/glance/db/0000775000175400017540000000000012323736427016017 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/db/migration.py0000664000175400017540000000277012323736226020365 0ustar jenkinsjenkins00000000000000# Copyright 2010 United States Government as represented by the # Administrator of the National Aeronautics and Space Administration. # All Rights Reserved. # # Copyright 2013 OpenStack Foundation # Copyright 2013 IBM Corp. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """Database setup and migration commands.""" import os from glance.common import utils from glance.db.sqlalchemy import api as db_api IMPL = utils.LazyPluggable( 'backend', config_group='database', sqlalchemy='glance.openstack.common.db.sqlalchemy.migration') INIT_VERSION = 0 MIGRATE_REPO_PATH = os.path.join( os.path.abspath(os.path.dirname(__file__)), 'sqlalchemy', 'migrate_repo', ) def db_sync(version=None, init_version=0): """Migrate the database to `version` or the most recent version.""" return IMPL.db_sync(engine=db_api.get_engine(), abs_path=MIGRATE_REPO_PATH, version=version, init_version=init_version) glance-2014.1/glance/db/sqlalchemy/0000775000175400017540000000000012323736427020161 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/db/sqlalchemy/models.py0000664000175400017540000002267412323736226022026 0ustar jenkinsjenkins00000000000000# Copyright 2010 United States Government as represented by the # Administrator of the National Aeronautics and Space Administration. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ SQLAlchemy models for glance data """ import uuid from sqlalchemy import BigInteger from sqlalchemy import Boolean from sqlalchemy import Column from sqlalchemy import DateTime from sqlalchemy.ext.compiler import compiles from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import ForeignKey from sqlalchemy import Index from sqlalchemy import Integer from sqlalchemy.orm import backref, relationship from sqlalchemy import String from sqlalchemy import Text from sqlalchemy.types import TypeDecorator from sqlalchemy import UniqueConstraint from glance.openstack.common.db.sqlalchemy import models from glance.openstack.common import jsonutils from glance.openstack.common import timeutils BASE = declarative_base() @compiles(BigInteger, 'sqlite') def compile_big_int_sqlite(type_, compiler, **kw): return 'INTEGER' class JSONEncodedDict(TypeDecorator): """Represents an immutable structure as a json-encoded string""" impl = Text def process_bind_param(self, value, dialect): if value is not None: value = jsonutils.dumps(value) return value def process_result_value(self, value, dialect): if value is not None: value = jsonutils.loads(value) return value class GlanceBase(models.ModelBase, models.TimestampMixin): """Base class for Glance Models.""" __table_args__ = {'mysql_engine': 'InnoDB'} __table_initialized__ = False __protected_attributes__ = set([ "created_at", "updated_at", "deleted_at", "deleted"]) def save(self, session=None): from glance.db.sqlalchemy import api as db_api super(GlanceBase, self).save(session or db_api.get_session()) created_at = Column(DateTime, default=lambda: timeutils.utcnow(), nullable=False) # TODO(vsergeyev): Column `updated_at` have no default value in # openstack common code. We should decide, is this value # required and make changes in oslo (if required) or # in glance (if not). updated_at = Column(DateTime, default=lambda: timeutils.utcnow(), nullable=False, onupdate=lambda: timeutils.utcnow()) # TODO(boris-42): Use SoftDeleteMixin instead of deleted Column after # migration that provides UniqueConstraints and change # type of this column. deleted_at = Column(DateTime) deleted = Column(Boolean, nullable=False, default=False) def delete(self, session=None): """Delete this object.""" self.deleted = True self.deleted_at = timeutils.utcnow() self.save(session=session) def keys(self): return self.__dict__.keys() def values(self): return self.__dict__.values() def items(self): return self.__dict__.items() def to_dict(self): d = self.__dict__.copy() # NOTE(flaper87): Remove # private state instance # It is not serializable # and causes CircularReference d.pop("_sa_instance_state") return d class Image(BASE, GlanceBase): """Represents an image in the datastore.""" __tablename__ = 'images' __table_args__ = (Index('checksum_image_idx', 'checksum'), Index('ix_images_is_public', 'is_public'), Index('ix_images_deleted', 'deleted'), Index('owner_image_idx', 'owner'),) id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4())) name = Column(String(255)) disk_format = Column(String(20)) container_format = Column(String(20)) size = Column(BigInteger) virtual_size = Column(BigInteger) status = Column(String(30), nullable=False) is_public = Column(Boolean, nullable=False, default=False) checksum = Column(String(32)) min_disk = Column(Integer, nullable=False, default=0) min_ram = Column(Integer, nullable=False, default=0) owner = Column(String(255)) protected = Column(Boolean, nullable=False, default=False) class ImageProperty(BASE, GlanceBase): """Represents an image properties in the datastore.""" __tablename__ = 'image_properties' __table_args__ = (Index('ix_image_properties_image_id', 'image_id'), Index('ix_image_properties_deleted', 'deleted'), UniqueConstraint('image_id', 'name', name='ix_image_properties_' 'image_id_name'),) id = Column(Integer, primary_key=True) image_id = Column(String(36), ForeignKey('images.id'), nullable=False) image = relationship(Image, backref=backref('properties')) name = Column(String(255), nullable=False) value = Column(Text) class ImageTag(BASE, GlanceBase): """Represents an image tag in the datastore.""" __tablename__ = 'image_tags' __table_args__ = (Index('ix_image_tags_image_id', 'image_id'), Index('ix_image_tags_image_id_tag_value', 'image_id', 'value'),) id = Column(Integer, primary_key=True, nullable=False) image_id = Column(String(36), ForeignKey('images.id'), nullable=False) image = relationship(Image, backref=backref('tags')) value = Column(String(255), nullable=False) class ImageLocation(BASE, GlanceBase): """Represents an image location in the datastore.""" __tablename__ = 'image_locations' __table_args__ = (Index('ix_image_locations_image_id', 'image_id'), Index('ix_image_locations_deleted', 'deleted'),) id = Column(Integer, primary_key=True, nullable=False) image_id = Column(String(36), ForeignKey('images.id'), nullable=False) image = relationship(Image, backref=backref('locations')) value = Column(Text(), nullable=False) meta_data = Column(JSONEncodedDict(), default={}) status = Column(String(30), default='active', nullable=False) class ImageMember(BASE, GlanceBase): """Represents an image members in the datastore.""" __tablename__ = 'image_members' unique_constraint_key_name = 'image_members_image_id_member_deleted_at_key' __table_args__ = (Index('ix_image_members_deleted', 'deleted'), Index('ix_image_members_image_id', 'image_id'), Index('ix_image_members_image_id_member', 'image_id', 'member'), UniqueConstraint('image_id', 'member', 'deleted_at', name=unique_constraint_key_name),) id = Column(Integer, primary_key=True) image_id = Column(String(36), ForeignKey('images.id'), nullable=False) image = relationship(Image, backref=backref('members')) member = Column(String(255), nullable=False) can_share = Column(Boolean, nullable=False, default=False) status = Column(String(20), nullable=False, default="pending") class Task(BASE, GlanceBase): """Represents an task in the datastore""" __tablename__ = 'tasks' __table_args__ = (Index('ix_tasks_type', 'type'), Index('ix_tasks_status', 'status'), Index('ix_tasks_owner', 'owner'), Index('ix_tasks_deleted', 'deleted'), Index('ix_tasks_updated_at', 'updated_at')) id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4())) type = Column(String(30)) status = Column(String(30)) owner = Column(String(255), nullable=False) expires_at = Column(DateTime, nullable=True) class TaskInfo(BASE, models.ModelBase): """Represents task info in the datastore""" __tablename__ = 'task_info' task_id = Column(String(36), ForeignKey('tasks.id'), primary_key=True, nullable=False) task = relationship(Task, backref=backref('info', uselist=False)) #NOTE(nikhil): input and result are stored as text in the DB. # SQLAlchemy marshals the data to/from JSON using custom type # JSONEncodedDict. It uses simplejson underneath. input = Column(JSONEncodedDict()) result = Column(JSONEncodedDict()) message = Column(Text) def register_models(engine): """Create database tables for all models with the given engine.""" models = (Image, ImageProperty, ImageMember) for model in models: model.metadata.create_all(engine) def unregister_models(engine): """Drop database tables for all models with the given engine.""" models = (Image, ImageProperty) for model in models: model.metadata.drop_all(engine) glance-2014.1/glance/db/sqlalchemy/api.py0000664000175400017540000013076312323736226021313 0ustar jenkinsjenkins00000000000000# Copyright 2010 United States Government as represented by the # Administrator of the National Aeronautics and Space Administration. # Copyright 2010-2011 OpenStack Foundation # Copyright 2012 Justin Santa Barbara # Copyright 2013 IBM Corp. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """Defines interface for DB access.""" from oslo.config import cfg from six.moves import xrange import sqlalchemy import sqlalchemy.orm as sa_orm import sqlalchemy.sql as sa_sql from glance.common import exception from glance.db.sqlalchemy import models from glance.openstack.common.db import exception as db_exception from glance.openstack.common.db.sqlalchemy import session import glance.openstack.common.log as os_logging from glance.openstack.common import timeutils BASE = models.BASE sa_logger = None LOG = os_logging.getLogger(__name__) STATUSES = ['active', 'saving', 'queued', 'killed', 'pending_delete', 'deleted'] CONF = cfg.CONF CONF.import_opt('debug', 'glance.openstack.common.log') CONF.import_opt('connection', 'glance.openstack.common.db.options', group='database') _FACADE = None def _create_facade_lazily(): global _FACADE if _FACADE is None: _FACADE = session.EngineFacade( CONF.database.connection, **dict(CONF.database.iteritems())) return _FACADE def get_engine(): facade = _create_facade_lazily() return facade.get_engine() def get_session(autocommit=True, expire_on_commit=False): facade = _create_facade_lazily() return facade.get_session(autocommit=autocommit, expire_on_commit=expire_on_commit) def clear_db_env(): """ Unset global configuration variables for database. """ global _FACADE _FACADE = None def _check_mutate_authorization(context, image_ref): if not is_image_mutable(context, image_ref): LOG.info(_("Attempted to modify image user did not own.")) msg = _("You do not own this image") if image_ref.is_public: exc_class = exception.ForbiddenPublicImage else: exc_class = exception.Forbidden raise exc_class(msg) def image_create(context, values): """Create an image from the values dictionary.""" return _image_update(context, values, None, purge_props=False) def image_update(context, image_id, values, purge_props=False, from_state=None): """ Set the given properties on an image and update it. :raises NotFound if image does not exist. """ return _image_update(context, values, image_id, purge_props, from_state=from_state) def image_destroy(context, image_id): """Destroy the image or raise if it does not exist.""" session = get_session() with session.begin(): image_ref = _image_get(context, image_id, session=session) # Perform authorization check _check_mutate_authorization(context, image_ref) image_ref.delete(session=session) delete_time = image_ref.deleted_at _image_locations_delete_all(context, image_ref.id, delete_time, session) _image_property_delete_all(context, image_id, delete_time, session) _image_member_delete_all(context, image_id, delete_time, session) _image_tag_delete_all(context, image_id, delete_time, session) return _normalize_locations(image_ref) def _normalize_locations(image): undeleted_locations = filter(lambda x: not x.deleted, image['locations']) image['locations'] = [{'url': loc['value'], 'metadata': loc['meta_data']} for loc in undeleted_locations] return image def image_get(context, image_id, session=None, force_show_deleted=False): image = _image_get(context, image_id, session=session, force_show_deleted=force_show_deleted) image = _normalize_locations(image.to_dict()) return image def _check_image_id(image_id): """ check if the given image id is valid before executing operations. For now, we only check its length. The original purpose of this method is wrapping the different behaviors between MySql and DB2 when the image id length is longer than the defined length in database model. :param image_id: The id of the image we want to check :return: Raise NoFound exception if given image id is invalid """ if image_id and \ len(image_id) > models.Image.id.property.columns[0].type.length: raise exception.NotFound() def _image_get(context, image_id, session=None, force_show_deleted=False): """Get an image or raise if it does not exist.""" _check_image_id(image_id) session = session or get_session() try: query = session.query(models.Image)\ .options(sa_orm.joinedload(models.Image.properties))\ .options(sa_orm.joinedload(models.Image.locations))\ .filter_by(id=image_id) # filter out deleted images if context disallows it if not force_show_deleted and not _can_show_deleted(context): query = query.filter_by(deleted=False) image = query.one() except sa_orm.exc.NoResultFound: msg = (_("No image found with ID %s") % image_id) LOG.debug(msg) raise exception.NotFound(msg) # Make sure they can look at it if not is_image_visible(context, image): msg = (_("Forbidding request, image %s not visible") % image_id) LOG.debug(msg) raise exception.Forbidden(msg) return image def is_image_mutable(context, image): """Return True if the image is mutable in this context.""" # Is admin == image mutable if context.is_admin: return True # No owner == image not mutable if image['owner'] is None or context.owner is None: return False # Image only mutable by its owner return image['owner'] == context.owner def is_image_visible(context, image, status=None): """Return True if the image is visible in this context.""" # Is admin == image visible if context.is_admin: return True # No owner == image visible if image['owner'] is None: return True # Image is_public == image visible if image['is_public']: return True # Perform tests based on whether we have an owner if context.owner is not None: if context.owner == image['owner']: return True # Figure out if this image is shared with that tenant members = image_member_find(context, image_id=image['id'], member=context.owner, status=status) if members: return True # Private image return False def _paginate_query(query, model, limit, sort_keys, marker=None, sort_dir=None, sort_dirs=None): """Returns a query with sorting / pagination criteria added. Pagination works by requiring a unique sort_key, specified by sort_keys. (If sort_keys is not unique, then we risk looping through values.) We use the last row in the previous page as the 'marker' for pagination. So we must return values that follow the passed marker in the order. With a single-valued sort_key, this would be easy: sort_key > X. With a compound-values sort_key, (k1, k2, k3) we must do this to repeat the lexicographical ordering: (k1 > X1) or (k1 == X1 && k2 > X2) or (k1 == X1 && k2 == X2 && k3 > X3) We also have to cope with different sort_directions. Typically, the id of the last row is used as the client-facing pagination marker, then the actual marker object must be fetched from the db and passed in to us as marker. :param query: the query object to which we should add paging/sorting :param model: the ORM model class :param limit: maximum number of items to return :param sort_keys: array of attributes by which results should be sorted :param marker: the last item of the previous page; we returns the next results after this value. :param sort_dir: direction in which results should be sorted (asc, desc) :param sort_dirs: per-column array of sort_dirs, corresponding to sort_keys :rtype: sqlalchemy.orm.query.Query :return: The query with sorting/pagination added. """ if 'id' not in sort_keys: # TODO(justinsb): If this ever gives a false-positive, check # the actual primary key, rather than assuming its id LOG.warn(_('Id not in sort_keys; is sort_keys unique?')) assert(not (sort_dir and sort_dirs)) # Default the sort direction to ascending if sort_dirs is None and sort_dir is None: sort_dir = 'asc' # Ensure a per-column sort direction if sort_dirs is None: sort_dirs = [sort_dir for _sort_key in sort_keys] assert(len(sort_dirs) == len(sort_keys)) # Add sorting for current_sort_key, current_sort_dir in zip(sort_keys, sort_dirs): sort_dir_func = { 'asc': sqlalchemy.asc, 'desc': sqlalchemy.desc, }[current_sort_dir] try: sort_key_attr = getattr(model, current_sort_key) except AttributeError: raise exception.InvalidSortKey() query = query.order_by(sort_dir_func(sort_key_attr)) default = '' # Default to an empty string if NULL # Add pagination if marker is not None: marker_values = [] for sort_key in sort_keys: v = getattr(marker, sort_key) if v is None: v = default marker_values.append(v) # Build up an array of sort criteria as in the docstring criteria_list = [] for i in xrange(len(sort_keys)): crit_attrs = [] for j in xrange(i): model_attr = getattr(model, sort_keys[j]) default = None if isinstance( model_attr.property.columns[0].type, sqlalchemy.DateTime) else '' attr = sa_sql.expression.case([(model_attr != None, model_attr), ], else_=default) crit_attrs.append((attr == marker_values[j])) model_attr = getattr(model, sort_keys[i]) default = None if isinstance(model_attr.property.columns[0].type, sqlalchemy.DateTime) else '' attr = sa_sql.expression.case([(model_attr != None, model_attr), ], else_=default) if sort_dirs[i] == 'desc': crit_attrs.append((attr < marker_values[i])) elif sort_dirs[i] == 'asc': crit_attrs.append((attr > marker_values[i])) else: raise ValueError(_("Unknown sort direction, " "must be 'desc' or 'asc'")) criteria = sa_sql.and_(*crit_attrs) criteria_list.append(criteria) f = sa_sql.or_(*criteria_list) query = query.filter(f) if limit is not None: query = query.limit(limit) return query def _make_conditions_from_filters(filters, is_public=None): #NOTE(venkatesh) make copy of the filters are to be altered in this method. filters = filters.copy() image_conditions = [] prop_conditions = [] tag_conditions = [] if is_public is not None: image_conditions.append(models.Image.is_public == is_public) if 'checksum' in filters: checksum = filters.pop('checksum') image_conditions.append(models.Image.checksum == checksum) if 'is_public' in filters: key = 'is_public' value = filters.pop('is_public') prop_filters = _make_image_property_condition(key=key, value=value) prop_conditions.append(prop_filters) for (k, v) in filters.pop('properties', {}).items(): prop_filters = _make_image_property_condition(key=k, value=v) prop_conditions.append(prop_filters) if 'changes-since' in filters: # normalize timestamp to UTC, as sqlalchemy doesn't appear to # respect timezone offsets changes_since = timeutils.normalize_time(filters.pop('changes-since')) image_conditions.append(models.Image.updated_at > changes_since) if 'deleted' in filters: deleted_filter = filters.pop('deleted') image_conditions.append(models.Image.deleted == deleted_filter) # TODO(bcwaldon): handle this logic in registry server if not deleted_filter: image_statuses = [s for s in STATUSES if s != 'killed'] image_conditions.append(models.Image.status.in_(image_statuses)) if 'tags' in filters: tags = filters.pop('tags') for tag in tags: tag_filters = [models.ImageTag.deleted == False] tag_filters.extend([models.ImageTag.value == tag]) tag_conditions.append(tag_filters) filters = dict([(k, v) for k, v in filters.items() if v is not None]) for (k, v) in filters.items(): key = k if k.endswith('_min') or k.endswith('_max'): key = key[0:-4] try: v = int(filters.pop(k)) except ValueError: msg = _("Unable to filter on a range " "with a non-numeric value.") raise exception.InvalidFilterRangeValue(msg) if k.endswith('_min'): image_conditions.append(getattr(models.Image, key) >= v) if k.endswith('_max'): image_conditions.append(getattr(models.Image, key) <= v) for (k, v) in filters.items(): value = filters.pop(k) if hasattr(models.Image, k): image_conditions.append(getattr(models.Image, k) == value) else: prop_filters = _make_image_property_condition(key=k, value=value) prop_conditions.append(prop_filters) return image_conditions, prop_conditions, tag_conditions def _make_image_property_condition(key, value): prop_filters = [models.ImageProperty.deleted == False] prop_filters.extend([models.ImageProperty.name == key]) prop_filters.extend([models.ImageProperty.value == value]) return prop_filters def _select_images_query(context, image_conditions, admin_as_user, member_status, visibility): session = get_session() img_conditional_clause = sa_sql.and_(*image_conditions) regular_user = (not context.is_admin) or admin_as_user query_member = session.query(models.Image) \ .join(models.Image.members) \ .filter(img_conditional_clause) if regular_user: member_filters = [models.ImageMember.deleted == False] if context.owner is not None: member_filters.extend([models.ImageMember.member == context.owner]) if member_status != 'all': member_filters.extend([ models.ImageMember.status == member_status]) query_member = query_member.filter(sa_sql.and_(*member_filters)) #NOTE(venkatesh) if the 'visibility' is set to 'shared', we just # query the image members table. No union is required. if visibility is not None and visibility == 'shared': return query_member query_image = session.query(models.Image)\ .filter(img_conditional_clause) if regular_user: query_image = query_image.filter(models.Image.is_public == True) query_image_owner = None if context.owner is not None: query_image_owner = session.query(models.Image) \ .filter(models.Image.owner == context.owner) \ .filter(img_conditional_clause) if query_image_owner is not None: query = query_image.union(query_image_owner, query_member) else: query = query_image.union(query_member) return query else: #Admin user return query_image def image_get_all(context, filters=None, marker=None, limit=None, sort_key='created_at', sort_dir='desc', member_status='accepted', is_public=None, admin_as_user=False): """ Get all images that match zero or more filters. :param filters: dict of filter keys and values. If a 'properties' key is present, it is treated as a dict of key/value filters on the image properties attribute :param marker: image id after which to start page :param limit: maximum number of images to return :param sort_key: image attribute by which results should be sorted :param sort_dir: direction in which results should be sorted (asc, desc) :param member_status: only return shared images that have this membership status :param is_public: If true, return only public images. If false, return only private and shared images. :param admin_as_user: For backwards compatibility. If true, then return to an admin the equivalent set of images which it would see if it were a regular user """ filters = filters or {} visibility = filters.pop('visibility', None) showing_deleted = 'changes-since' in filters or filters.get('deleted', False) img_conditions, prop_conditions, tag_conditions = \ _make_conditions_from_filters(filters, is_public) query = _select_images_query(context, img_conditions, admin_as_user, member_status, visibility) if visibility is not None: if visibility == 'public': query = query.filter(models.Image.is_public == True) elif visibility == 'private': query = query.filter(models.Image.is_public == False) if prop_conditions: for prop_condition in prop_conditions: query = query.join(models.ImageProperty, aliased=True)\ .filter(sa_sql.and_(*prop_condition)) if tag_conditions: for tag_condition in tag_conditions: query = query.join(models.ImageTag, aliased=True)\ .filter(sa_sql.and_(*tag_condition)) marker_image = None if marker is not None: marker_image = _image_get(context, marker, force_show_deleted=showing_deleted) sort_keys = ['created_at', 'id'] sort_keys.insert(0, sort_key) if sort_key not in sort_keys else sort_keys query = _paginate_query(query, models.Image, limit, sort_keys, marker=marker_image, sort_dir=sort_dir) query = query.options(sa_orm.joinedload(models.Image.properties))\ .options(sa_orm.joinedload(models.Image.locations)) return [_normalize_locations(image.to_dict()) for image in query.all()] def _drop_protected_attrs(model_class, values): """ Removed protected attributes from values dictionary using the models __protected_attributes__ field. """ for attr in model_class.__protected_attributes__: if attr in values: del values[attr] def _image_get_disk_usage_by_owner(owner, session, image_id=None): query = session.query(models.Image) query = query.filter(models.Image.owner == owner) if image_id is not None: query = query.filter(models.Image.id != image_id) query = query.filter(models.Image.size > 0) query = query.filter(~models.Image.status.in_(['killed', 'pending_delete', 'deleted'])) images = query.all() total = 0 for i in images: locations = [l for l in i.locations if not l['deleted']] total += (i.size * len(locations)) return total def _validate_image(values): """ Validates the incoming data and raises a Invalid exception if anything is out of order. :param values: Mapping of image metadata to check """ status = values.get('status') if not status: msg = "Image status is required." raise exception.Invalid(msg) if status not in STATUSES: msg = "Invalid image status '%s' for image." % status raise exception.Invalid(msg) return values def _update_values(image_ref, values): for k in values: if getattr(image_ref, k) != values[k]: setattr(image_ref, k, values[k]) def _image_update(context, values, image_id, purge_props=False, from_state=None): """ Used internally by image_create and image_update :param context: Request context :param values: A dict of attributes to set :param image_id: If None, create the image, otherwise, find and update it """ #NOTE(jbresnah) values is altered in this so a copy is needed values = values.copy() session = get_session() with session.begin(): # Remove the properties passed in the values mapping. We # handle properties separately from base image attributes, # and leaving properties in the values mapping will cause # a SQLAlchemy model error because SQLAlchemy expects the # properties attribute of an Image model to be a list and # not a dict. properties = values.pop('properties', {}) location_data = values.pop('locations', None) new_status = values.get('status', None) if image_id: image_ref = _image_get(context, image_id, session=session) current = image_ref.status # Perform authorization check _check_mutate_authorization(context, image_ref) else: if values.get('size') is not None: values['size'] = int(values['size']) if 'min_ram' in values: values['min_ram'] = int(values['min_ram'] or 0) if 'min_disk' in values: values['min_disk'] = int(values['min_disk'] or 0) values['is_public'] = bool(values.get('is_public', False)) values['protected'] = bool(values.get('protected', False)) image_ref = models.Image() # Need to canonicalize ownership if 'owner' in values and not values['owner']: values['owner'] = None if image_id: # Don't drop created_at if we're passing it in... _drop_protected_attrs(models.Image, values) #NOTE(iccha-sethi): updated_at must be explicitly set in case # only ImageProperty table was modifited values['updated_at'] = timeutils.utcnow() if image_id: query = session.query(models.Image).filter_by(id=image_id) if from_state: query = query.filter_by(status=from_state) if new_status: _validate_image(values) # Validate fields for Images table. This is similar to what is done # for the query result update except that we need to do it prior # in this case. # TODO(dosaboy): replace this with a dict comprehension once py26 # support is deprecated. keys = values.keys() for k in keys: if k not in image_ref.to_dict(): del values[k] updated = query.update(values, synchronize_session='fetch') if not updated: msg = (_('cannot transition from %(current)s to ' '%(next)s in update (wanted ' 'from_state=%(from)s)') % {'current': current, 'next': new_status, 'from': from_state}) raise exception.Conflict(msg) image_ref = _image_get(context, image_id, session=session) else: image_ref.update(values) # Validate the attributes before we go any further. From my # investigation, the @validates decorator does not validate # on new records, only on existing records, which is, well, # idiotic. values = _validate_image(image_ref.to_dict()) _update_values(image_ref, values) try: image_ref.save(session=session) except db_exception.DBDuplicateEntry: raise exception.Duplicate("Image ID %s already exists!" % values['id']) _set_properties_for_image(context, image_ref, properties, purge_props, session) if location_data is not None: _image_locations_set(image_ref.id, location_data, session) return image_get(context, image_ref.id) def _image_locations_set(image_id, locations, session): location_refs = session.query(models.ImageLocation)\ .filter_by(image_id=image_id)\ .filter_by(deleted=False)\ .all() for location_ref in location_refs: location_ref.delete(session=session) for location in locations: location_ref = models.ImageLocation(image_id=image_id, value=location['url'], meta_data=location['metadata']) location_ref.save() def _image_locations_delete_all(context, image_id, delete_time=None, session=None): """Delete all image locations for given image""" locs_updated_count = _image_child_entry_delete_all(models.ImageLocation, image_id, delete_time, session) return locs_updated_count def _set_properties_for_image(context, image_ref, properties, purge_props=False, session=None): """ Create or update a set of image_properties for a given image :param context: Request context :param image_ref: An Image object :param properties: A dict of properties to set :param session: A SQLAlchemy session to use (if present) """ orig_properties = {} for prop_ref in image_ref.properties: orig_properties[prop_ref.name] = prop_ref for name, value in properties.iteritems(): prop_values = {'image_id': image_ref.id, 'name': name, 'value': value} if name in orig_properties: prop_ref = orig_properties[name] _image_property_update(context, prop_ref, prop_values, session=session) else: image_property_create(context, prop_values, session=session) if purge_props: for key in orig_properties.keys(): if key not in properties: prop_ref = orig_properties[key] image_property_delete(context, prop_ref.name, image_ref.id, session=session) def _image_child_entry_delete_all(child_model_cls, image_id, delete_time=None, session=None): """Deletes all the child entries for the given image id. Deletes all the child entries of the given child entry ORM model class using the parent image's id. The child entry ORM model class can be one of the following: model.ImageLocation, model.ImageProperty, model.ImageMember and model.ImageTag. :param child_model_cls: the ORM model class. :param image_id: id of the image whose child entries are to be deleted. :param delete_time: datetime of deletion to be set. If None, uses current datetime. :param session: A SQLAlchemy session to use (if present) :rtype: int :return: The number of child entries got soft-deleted. """ session = session or get_session() query = session.query(child_model_cls) \ .filter_by(image_id=image_id) \ .filter_by(deleted=False) delete_time = delete_time or timeutils.utcnow() count = query.update({"deleted": True, "deleted_at": delete_time}) return count def image_property_create(context, values, session=None): """Create an ImageProperty object.""" prop_ref = models.ImageProperty() prop = _image_property_update(context, prop_ref, values, session=session) return prop.to_dict() def _image_property_update(context, prop_ref, values, session=None): """ Used internally by image_property_create and image_property_update. """ _drop_protected_attrs(models.ImageProperty, values) values["deleted"] = False prop_ref.update(values) prop_ref.save(session=session) return prop_ref def image_property_delete(context, prop_ref, image_ref, session=None): """ Used internally by image_property_create and image_property_update. """ session = session or get_session() prop = session.query(models.ImageProperty).filter_by(image_id=image_ref, name=prop_ref).one() prop.delete(session=session) return prop def _image_property_delete_all(context, image_id, delete_time=None, session=None): """Delete all image properties for given image""" props_updated_count = _image_child_entry_delete_all(models.ImageProperty, image_id, delete_time, session) return props_updated_count def image_member_create(context, values, session=None): """Create an ImageMember object.""" memb_ref = models.ImageMember() _image_member_update(context, memb_ref, values, session=session) return _image_member_format(memb_ref) def _image_member_format(member_ref): """Format a member ref for consumption outside of this module.""" return { 'id': member_ref['id'], 'image_id': member_ref['image_id'], 'member': member_ref['member'], 'can_share': member_ref['can_share'], 'status': member_ref['status'], 'created_at': member_ref['created_at'], 'updated_at': member_ref['updated_at'] } def image_member_update(context, memb_id, values): """Update an ImageMember object.""" session = get_session() memb_ref = _image_member_get(context, memb_id, session) _image_member_update(context, memb_ref, values, session) return _image_member_format(memb_ref) def _image_member_update(context, memb_ref, values, session=None): """Apply supplied dictionary of values to a Member object.""" _drop_protected_attrs(models.ImageMember, values) values["deleted"] = False values.setdefault('can_share', False) memb_ref.update(values) memb_ref.save(session=session) return memb_ref def image_member_delete(context, memb_id, session=None): """Delete an ImageMember object.""" session = session or get_session() member_ref = _image_member_get(context, memb_id, session) _image_member_delete(context, member_ref, session) def _image_member_delete(context, memb_ref, session): memb_ref.delete(session=session) def _image_member_delete_all(context, image_id, delete_time=None, session=None): """Delete all image members for given image""" members_updated_count = _image_child_entry_delete_all(models.ImageMember, image_id, delete_time, session) return members_updated_count def _image_member_get(context, memb_id, session): """Fetch an ImageMember entity by id.""" query = session.query(models.ImageMember) query = query.filter_by(id=memb_id) return query.one() def image_member_find(context, image_id=None, member=None, status=None): """Find all members that meet the given criteria :param image_id: identifier of image entity :param member: tenant to which membership has been granted """ session = get_session() members = _image_member_find(context, session, image_id, member, status) return [_image_member_format(m) for m in members] def _image_member_find(context, session, image_id=None, member=None, status=None): query = session.query(models.ImageMember) query = query.filter_by(deleted=False) if not context.is_admin: query = query.join(models.Image) filters = [ models.Image.owner == context.owner, models.ImageMember.member == context.owner, ] query = query.filter(sa_sql.or_(*filters)) if image_id is not None: query = query.filter(models.ImageMember.image_id == image_id) if member is not None: query = query.filter(models.ImageMember.member == member) if status is not None: query = query.filter(models.ImageMember.status == status) return query.all() def image_member_count(context, image_id): """Return the number of image members for this image :param image_id: identifier of image entity """ session = get_session() if not image_id: msg = _("Image id is required.") raise exception.Invalid(msg) query = session.query(models.ImageMember) query = query.filter_by(deleted=False) query = query.filter(models.ImageMember.image_id == str(image_id)) return query.count() # pylint: disable-msg=C0111 def _can_show_deleted(context): """ Calculates whether to include deleted objects based on context. Currently just looks for a flag called deleted in the context dict. """ if hasattr(context, 'show_deleted'): return context.show_deleted if not hasattr(context, 'get'): return False return context.get('deleted', False) def image_tag_set_all(context, image_id, tags): session = get_session() existing_tags = set(image_tag_get_all(context, image_id, session)) tags = set(tags) tags_to_create = tags - existing_tags #NOTE(bcwaldon): we call 'reversed' here to ensure the ImageTag.id fields # will be populated in the order required to reflect the correct ordering # on a subsequent call to image_tag_get_all for tag in reversed(list(tags_to_create)): image_tag_create(context, image_id, tag, session) tags_to_delete = existing_tags - tags for tag in tags_to_delete: image_tag_delete(context, image_id, tag, session) def image_tag_create(context, image_id, value, session=None): """Create an image tag.""" session = session or get_session() tag_ref = models.ImageTag(image_id=image_id, value=value) tag_ref.save(session=session) return tag_ref['value'] def image_tag_delete(context, image_id, value, session=None): """Delete an image tag.""" _check_image_id(image_id) session = session or get_session() query = session.query(models.ImageTag)\ .filter_by(image_id=image_id)\ .filter_by(value=value)\ .filter_by(deleted=False) try: tag_ref = query.one() except sa_orm.exc.NoResultFound: raise exception.NotFound() tag_ref.delete(session=session) def _image_tag_delete_all(context, image_id, delete_time=None, session=None): """Delete all image tags for given image""" tags_updated_count = _image_child_entry_delete_all(models.ImageTag, image_id, delete_time, session) return tags_updated_count def image_tag_get_all(context, image_id, session=None): """Get a list of tags for a specific image.""" _check_image_id(image_id) session = session or get_session() tags = session.query(models.ImageTag)\ .filter_by(image_id=image_id)\ .filter_by(deleted=False)\ .order_by(sqlalchemy.asc(models.ImageTag.created_at))\ .all() return [tag['value'] for tag in tags] def user_get_storage_usage(context, owner_id, image_id=None, session=None): _check_image_id(image_id) session = session or get_session() total_size = _image_get_disk_usage_by_owner( owner_id, session, image_id=image_id) return total_size def _task_info_format(task_info_ref): """Format a task info ref for consumption outside of this module""" if task_info_ref is None: return {} return { 'task_id': task_info_ref['task_id'], 'input': task_info_ref['input'], 'result': task_info_ref['result'], 'message': task_info_ref['message'], } def _task_info_create(context, task_id, values, session=None): """Create an TaskInfo object""" session = session or get_session() task_info_ref = models.TaskInfo() task_info_ref.task_id = task_id task_info_ref.update(values) task_info_ref.save(session=session) return _task_info_format(task_info_ref) def _task_info_update(context, task_id, values, session=None): """Update an TaskInfo object""" session = session or get_session() task_info_ref = _task_info_get(context, task_id, session=session) if task_info_ref: task_info_ref.update(values) task_info_ref.save(session=session) return _task_info_format(task_info_ref) def _task_info_get(context, task_id, session=None): """Fetch an TaskInfo entity by task_id""" session = session or get_session() query = session.query(models.TaskInfo) query = query.filter_by(task_id=task_id) try: task_info_ref = query.one() except sa_orm.exc.NoResultFound: msg = (_("TaskInfo was not found for task with id %(task_id)s") % {'task_id': task_id}) LOG.debug(msg) task_info_ref = None return task_info_ref def task_create(context, values, session=None): """Create a task object""" values = values.copy() session = session or get_session() with session.begin(): task_info_values = _pop_task_info_values(values) task_ref = models.Task() _task_update(context, task_ref, values, session=session) _task_info_create(context, task_ref.id, task_info_values, session=session) return task_get(context, task_ref.id, session) def _pop_task_info_values(values): task_info_values = {} for k, v in values.items(): if k in ['input', 'result', 'message']: values.pop(k) task_info_values[k] = v return task_info_values def task_update(context, task_id, values, session=None): """Update a task object""" session = session or get_session() with session.begin(): task_info_values = _pop_task_info_values(values) task_ref = _task_get(context, task_id, session) _drop_protected_attrs(models.Task, values) values['updated_at'] = timeutils.utcnow() _task_update(context, task_ref, values, session) if task_info_values: _task_info_update(context, task_id, task_info_values, session) return task_get(context, task_id, session) def task_get(context, task_id, session=None, force_show_deleted=False): """Fetch a task entity by id""" task_ref = _task_get(context, task_id, session=session, force_show_deleted=force_show_deleted) return _task_format(task_ref, task_ref.info) def task_delete(context, task_id, session=None): """Delete a task""" session = session or get_session() task_ref = _task_get(context, task_id, session=session) task_ref.delete(session=session) return _task_format(task_ref, task_ref.info) def task_get_all(context, filters=None, marker=None, limit=None, sort_key='created_at', sort_dir='desc', admin_as_user=False): """ Get all tasks that match zero or more filters. :param filters: dict of filter keys and values. :param marker: task id after which to start page :param limit: maximum number of tasks to return :param sort_key: task attribute by which results should be sorted :param sort_dir: direction in which results should be sorted (asc, desc) :param admin_as_user: For backwards compatibility. If true, then return to an admin the equivalent set of tasks which it would see if it were a regular user :return: tasks set """ filters = filters or {} session = get_session() query = session.query(models.Task) if not (context.is_admin or admin_as_user == True) and \ context.owner is not None: query = query.filter(models.Task.owner == context.owner) showing_deleted = False if 'deleted' in filters: deleted_filter = filters.pop('deleted') query = query.filter_by(deleted=deleted_filter) showing_deleted = deleted_filter for (k, v) in filters.items(): if v is not None: key = k if hasattr(models.Task, key): query = query.filter(getattr(models.Task, key) == v) marker_task = None if marker is not None: marker_task = _task_get(context, marker, force_show_deleted=showing_deleted) sort_keys = ['created_at', 'id'] if sort_key not in sort_keys: sort_keys.insert(0, sort_key) query = _paginate_query(query, models.Task, limit, sort_keys, marker=marker_task, sort_dir=sort_dir) task_refs = query.all() tasks = [] for task_ref in task_refs: tasks.append(_task_format(task_ref, task_info_ref=None)) return tasks def _is_task_visible(context, task): """Return True if the task is visible in this context.""" # Is admin == task visible if context.is_admin: return True # No owner == task visible if task['owner'] is None: return True # Perform tests based on whether we have an owner if context.owner is not None: if context.owner == task['owner']: return True return False def _task_get(context, task_id, session=None, force_show_deleted=False): """Fetch a task entity by id""" session = session or get_session() query = session.query(models.Task).options( sa_orm.joinedload(models.Task.info) ).filter_by(id=task_id) if not force_show_deleted and not _can_show_deleted(context): query = query.filter_by(deleted=False) try: task_ref = query.one() except sa_orm.exc.NoResultFound: msg = (_("No task found with ID %s") % task_id) LOG.debug(msg) raise exception.TaskNotFound(task_id=task_id) # Make sure the task is visible if not _is_task_visible(context, task_ref): msg = (_("Forbidding request, task %s is not visible") % task_id) LOG.debug(msg) raise exception.Forbidden(msg) return task_ref def _task_update(context, task_ref, values, session=None): """Apply supplied dictionary of values to a task object.""" values["deleted"] = False task_ref.update(values) task_ref.save(session=session) return task_ref def _task_format(task_ref, task_info_ref=None): """Format a task ref for consumption outside of this module""" task_dict = { 'id': task_ref['id'], 'type': task_ref['type'], 'status': task_ref['status'], 'owner': task_ref['owner'], 'expires_at': task_ref['expires_at'], 'created_at': task_ref['created_at'], 'updated_at': task_ref['updated_at'], 'deleted_at': task_ref['deleted_at'], 'deleted': task_ref['deleted'] } if task_info_ref: task_info_dict = { 'input': task_info_ref['input'], 'result': task_info_ref['result'], 'message': task_info_ref['message'], } task_dict.update(task_info_dict) return task_dict glance-2014.1/glance/db/sqlalchemy/migrate_repo/0000775000175400017540000000000012323736427022636 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/db/sqlalchemy/migrate_repo/versions/0000775000175400017540000000000012323736427024506 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/db/sqlalchemy/migrate_repo/versions/021_set_engine_mysql_innodb.py0000664000175400017540000000225312323736226032337 0ustar jenkinsjenkins00000000000000# Copyright 2013 OpenStack Foundation # All Rights Reserved. # Copyright 2013 IBM Corp. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from sqlalchemy import MetaData tables = ['image_locations'] def upgrade(migrate_engine): meta = MetaData() meta.bind = migrate_engine if migrate_engine.name == "mysql": d = migrate_engine.execute("SHOW TABLE STATUS WHERE Engine!='InnoDB';") for row in d.fetchall(): table_name = row[0] if table_name in tables: migrate_engine.execute("ALTER TABLE %s Engine=InnoDB" % table_name) def downgrade(migrate_engine): pass glance-2014.1/glance/db/sqlalchemy/migrate_repo/versions/027_checksum_index.py0000664000175400017540000000217612323736226030444 0ustar jenkinsjenkins00000000000000# Copyright 2013 Rackspace Hosting # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from sqlalchemy import MetaData, Table, Index INDEX_NAME = 'checksum_image_idx' def upgrade(migrate_engine): meta = MetaData() meta.bind = migrate_engine images = Table('images', meta, autoload=True) index = Index(INDEX_NAME, images.c.checksum) index.create(migrate_engine) def downgrade(migrate_engine): meta = MetaData() meta.bind = migrate_engine images = Table('images', meta, autoload=True) index = Index(INDEX_NAME, images.c.checksum) index.drop(migrate_engine) glance-2014.1/glance/db/sqlalchemy/migrate_repo/versions/019_migrate_image_locations.py0000664000175400017540000000374712323736226032326 0ustar jenkinsjenkins00000000000000# Copyright 2013 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import sqlalchemy def get_images_table(meta): return sqlalchemy.Table('images', meta, autoload=True) def get_image_locations_table(meta): return sqlalchemy.Table('image_locations', meta, autoload=True) def upgrade(migrate_engine): meta = sqlalchemy.schema.MetaData(migrate_engine) images_table = get_images_table(meta) image_locations_table = get_image_locations_table(meta) image_records = images_table.select().execute().fetchall() for image in image_records: if image.location is not None: values = { 'image_id': image.id, 'value': image.location, 'created_at': image.created_at, 'updated_at': image.updated_at, 'deleted': image.deleted, 'deleted_at': image.deleted_at, } image_locations_table.insert(values=values).execute() def downgrade(migrate_engine): meta = sqlalchemy.schema.MetaData(migrate_engine) images_table = get_images_table(meta) image_locations_table = get_image_locations_table(meta) image_records = image_locations_table.select().execute().fetchall() for image_location in image_records: images_table.update(values={'location': image_location.value})\ .where(images_table.c.id == image_location.image_id)\ .execute() glance-2014.1/glance/db/sqlalchemy/migrate_repo/versions/006_mysql_downgrade.sql0000664000175400017540000000055012323736226031010 0ustar jenkinsjenkins00000000000000/* * This file is necessary because MySQL does not support * renaming indexes. */ DROP INDEX ix_image_properties_image_id_name ON image_properties; /* Rename the `key` column to `name` */ ALTER TABLE image_properties CHANGE COLUMN name `key` VARCHAR(255) NOT NULL; CREATE UNIQUE INDEX ix_image_properties_image_id_key ON image_properties (image_id, key); glance-2014.1/glance/db/sqlalchemy/migrate_repo/versions/005_size_big_integer.py0000664000175400017540000000740412323736226030756 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from migrate.changeset import * # noqa from sqlalchemy import * # noqa from glance.db.sqlalchemy.migrate_repo.schema import ( Boolean, DateTime, BigInteger, Integer, String, Text, from_migration_import) # noqa def get_images_table(meta): """ Returns the Table object for the images table that corresponds to the images table definition of this version. """ images = Table('images', meta, Column('id', Integer(), primary_key=True, nullable=False), Column('name', String(255)), Column('disk_format', String(20)), Column('container_format', String(20)), Column('size', BigInteger()), Column('status', String(30), nullable=False), Column('is_public', Boolean(), nullable=False, default=False, index=True), Column('location', Text()), Column('created_at', DateTime(), nullable=False), Column('updated_at', DateTime()), Column('deleted_at', DateTime()), Column('deleted', Boolean(), nullable=False, default=False, index=True), mysql_engine='InnoDB', extend_existing=True) return images def get_image_properties_table(meta): """ No changes to the image properties table from 002... """ (define_image_properties_table,) = from_migration_import( '002_add_image_properties_table', ['define_image_properties_table']) image_properties = define_image_properties_table(meta) return image_properties def upgrade(migrate_engine): meta = MetaData() meta.bind = migrate_engine # No changes to SQLite stores are necessary, since # there is no BIG INTEGER type in SQLite. Unfortunately, # running the Python 005_size_big_integer.py migration script # on a SQLite datastore results in an error in the sa-migrate # code that does the workarounds for SQLite not having # ALTER TABLE MODIFY COLUMN ability dialect = migrate_engine.url.get_dialect().name if not dialect.startswith('sqlite'): (get_images_table,) = from_migration_import( '003_add_disk_format', ['get_images_table']) images = get_images_table(meta) images.columns['size'].alter(type=BigInteger()) def downgrade(migrate_engine): meta = MetaData() meta.bind = migrate_engine # No changes to SQLite stores are necessary, since # there is no BIG INTEGER type in SQLite. Unfortunately, # running the Python 005_size_big_integer.py migration script # on a SQLite datastore results in an error in the sa-migrate # code that does the workarounds for SQLite not having # ALTER TABLE MODIFY COLUMN ability dialect = migrate_engine.url.get_dialect().name if not dialect.startswith('sqlite'): images = get_images_table(meta) images.columns['size'].alter(type=Integer()) glance-2014.1/glance/db/sqlalchemy/migrate_repo/versions/031_remove_duplicated_locations.py0000664000175400017540000000600012323736226033202 0ustar jenkinsjenkins00000000000000# Copyright 2013 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. import sqlalchemy from sqlalchemy import func from sqlalchemy import orm from sqlalchemy import sql from sqlalchemy import Table def upgrade(migrate_engine): meta = sqlalchemy.schema.MetaData(migrate_engine) image_locations = Table('image_locations', meta, autoload=True) if migrate_engine.name == "ibm_db_sa": il = orm.aliased(image_locations) # NOTE(wenchma): Get all duplicated rows. qry = (sql.select([il.c.id]) .where(il.c.id > (sql.select([func.min(image_locations.c.id)]) .where(image_locations.c.image_id == il.c.image_id) .where(image_locations.c.value == il.c.value) .where(image_locations.c.meta_data == il.c.meta_data) .where(image_locations.c.deleted == False))) .where(il.c.deleted == False) .execute() ) for row in qry: stmt = (image_locations.delete() .where(image_locations.c.id == row[0]) .where(image_locations.c.deleted == False)) stmt.execute() else: session = orm.sessionmaker(bind=migrate_engine)() # NOTE(flaper87): Lets group by # image_id, location and metadata. grp = [image_locations.c.image_id, image_locations.c.value, image_locations.c.meta_data] # NOTE(flaper87): Get all duplicated rows qry = (session.query(*grp) .filter(image_locations.c.deleted == False) .group_by(*grp) .having(func.count() > 1)) for row in qry: # NOTE(flaper87): Not the fastest way to do it. # This is the best way to do it since sqlalchemy # has a bug around delete + limit. s = (sql.select([image_locations.c.id]) .where(image_locations.c.image_id == row[0]) .where(image_locations.c.value == row[1]) .where(image_locations.c.meta_data == row[2]) .where(image_locations.c.deleted == False) .limit(1).execute()) stmt = (image_locations.delete() .where(image_locations.c.id == s.first()[0])) stmt.execute() session.close() def downgrade(migrate_engine): # NOTE(flaper87): There's no downgrade # path for this. return glance-2014.1/glance/db/sqlalchemy/migrate_repo/versions/012_id_to_uuid.py0000664000175400017540000004752312323736226027576 0ustar jenkinsjenkins00000000000000# Copyright 2013 IBM Corp. # Copyright 2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ While SQLAlchemy/sqlalchemy-migrate should abstract this correctly, there are known issues with these libraries so SQLite and non-SQLite migrations must be done separately. """ import uuid import migrate import sqlalchemy meta = sqlalchemy.MetaData() and_ = sqlalchemy.and_ or_ = sqlalchemy.or_ def upgrade(migrate_engine): """ Call the correct dialect-specific upgrade. """ meta.bind = migrate_engine t_images = _get_table('images', meta) t_image_members = _get_table('image_members', meta) t_image_properties = _get_table('image_properties', meta) dialect = migrate_engine.url.get_dialect().name if dialect == "sqlite": _upgrade_sqlite(t_images, t_image_members, t_image_properties) _update_all_ids_to_uuids(t_images, t_image_members, t_image_properties) elif dialect == "ibm_db_sa": _upgrade_db2(t_images, t_image_members, t_image_properties) _update_all_ids_to_uuids(t_images, t_image_members, t_image_properties) _add_db2_constraints() else: _upgrade_other(t_images, t_image_members, t_image_properties, dialect) def downgrade(migrate_engine): """ Call the correct dialect-specific downgrade. """ meta.bind = migrate_engine t_images = _get_table('images', meta) t_image_members = _get_table('image_members', meta) t_image_properties = _get_table('image_properties', meta) dialect = migrate_engine.url.get_dialect().name if dialect == "sqlite": _update_all_uuids_to_ids(t_images, t_image_members, t_image_properties) _downgrade_sqlite(t_images, t_image_members, t_image_properties) elif dialect == "ibm_db_sa": _remove_db2_constraints() _update_all_uuids_to_ids(t_images, t_image_members, t_image_properties) _downgrade_db2(t_images, t_image_members, t_image_properties) else: _downgrade_other(t_images, t_image_members, t_image_properties, dialect) def _upgrade_sqlite(t_images, t_image_members, t_image_properties): """ Upgrade 011 -> 012 with special SQLite-compatible logic. """ sql_commands = [ """CREATE TABLE images_backup ( id VARCHAR(36) NOT NULL, name VARCHAR(255), size INTEGER, status VARCHAR(30) NOT NULL, is_public BOOLEAN NOT NULL, location TEXT, created_at DATETIME NOT NULL, updated_at DATETIME, deleted_at DATETIME, deleted BOOLEAN NOT NULL, disk_format VARCHAR(20), container_format VARCHAR(20), checksum VARCHAR(32), owner VARCHAR(255), min_disk INTEGER NOT NULL, min_ram INTEGER NOT NULL, PRIMARY KEY (id), CHECK (is_public IN (0, 1)), CHECK (deleted IN (0, 1)) );""", """INSERT INTO images_backup SELECT * FROM images;""", """CREATE TABLE image_members_backup ( id INTEGER NOT NULL, image_id VARCHAR(36) NOT NULL, member VARCHAR(255) NOT NULL, can_share BOOLEAN NOT NULL, created_at DATETIME NOT NULL, updated_at DATETIME, deleted_at DATETIME, deleted BOOLEAN NOT NULL, PRIMARY KEY (id), UNIQUE (image_id, member), CHECK (can_share IN (0, 1)), CHECK (deleted IN (0, 1)), FOREIGN KEY(image_id) REFERENCES images (id) );""", """INSERT INTO image_members_backup SELECT * FROM image_members;""", """CREATE TABLE image_properties_backup ( id INTEGER NOT NULL, image_id VARCHAR(36) NOT NULL, name VARCHAR(255) NOT NULL, value TEXT, created_at DATETIME NOT NULL, updated_at DATETIME, deleted_at DATETIME, deleted BOOLEAN NOT NULL, PRIMARY KEY (id), CHECK (deleted IN (0, 1)), UNIQUE (image_id, name), FOREIGN KEY(image_id) REFERENCES images (id) );""", """INSERT INTO image_properties_backup SELECT * FROM image_properties;""", ] for command in sql_commands: meta.bind.execute(command) _sqlite_table_swap(t_image_members, t_image_properties, t_images) def _upgrade_db2(t_images, t_image_members, t_image_properties): """ Upgrade for DB2. """ t_images.c.id.alter(sqlalchemy.String(36), primary_key=True) image_members_backup = sqlalchemy.Table( 'image_members_backup', meta, sqlalchemy.Column('id', sqlalchemy.Integer(), primary_key=True, nullable=False), sqlalchemy.Column('image_id', sqlalchemy.String(36), nullable=False, index=True), sqlalchemy.Column('member', sqlalchemy.String(255), nullable=False), sqlalchemy.Column('can_share', sqlalchemy.Boolean(), nullable=False, default=False), sqlalchemy.Column('created_at', sqlalchemy.DateTime(), nullable=False), sqlalchemy.Column('updated_at', sqlalchemy.DateTime()), sqlalchemy.Column('deleted_at', sqlalchemy.DateTime()), sqlalchemy.Column('deleted', sqlalchemy.Boolean(), nullable=False, default=False, index=True), sqlalchemy.UniqueConstraint('image_id', 'member'), extend_existing=True) image_properties_backup = sqlalchemy.Table( 'image_properties_backup', meta, sqlalchemy.Column('id', sqlalchemy.Integer(), primary_key=True, nullable=False), sqlalchemy.Column('image_id', sqlalchemy.String(36), nullable=False, index=True), sqlalchemy.Column('name', sqlalchemy.String(255), nullable=False), sqlalchemy.Column('value', sqlalchemy.Text()), sqlalchemy.Column('created_at', sqlalchemy.DateTime(), nullable=False), sqlalchemy.Column('updated_at', sqlalchemy.DateTime()), sqlalchemy.Column('deleted_at', sqlalchemy.DateTime()), sqlalchemy.Column('deleted', sqlalchemy.Boolean(), nullable=False, default=False, index=True), sqlalchemy.UniqueConstraint( 'image_id', 'name', name='ix_image_properties_image_id_name'), extend_existing=True) image_members_backup.create() image_properties_backup.create() sql_commands = [ """INSERT INTO image_members_backup SELECT * FROM image_members;""", """INSERT INTO image_properties_backup SELECT * FROM image_properties;""", ] for command in sql_commands: meta.bind.execute(command) t_image_members.drop() t_image_properties.drop() image_members_backup.rename(name='image_members') image_properties_backup.rename(name='image_properties') def _add_db2_constraints(): #Create the foreign keys sql_commands = [ """ALTER TABLE image_members ADD CONSTRAINT member_image_id FOREIGN KEY (image_id) REFERENCES images (id);""", """ALTER TABLE image_properties ADD CONSTRAINT property_image_id FOREIGN KEY (image_id) REFERENCES images (id);""", ] for command in sql_commands: meta.bind.execute(command) def _remove_db2_constraints(): #remove the foreign keys constraints sql_commands = [ """ALTER TABLE image_members DROP CONSTRAINT member_image_id;""", """ALTER TABLE image_properties DROP CONSTRAINT property_image_id;""" ] for command in sql_commands: meta.bind.execute(command) def _downgrade_db2(t_images, t_image_members, t_image_properties): """ Downgrade for DB2. """ t_images.c.id.alter(sqlalchemy.Integer(), primary_key=True) image_members_old = sqlalchemy.Table( 'image_members_old', meta, sqlalchemy.Column('id', sqlalchemy.Integer(), primary_key=True, nullable=False), sqlalchemy.Column('image_id', sqlalchemy.Integer(), nullable=False, index=True), sqlalchemy.Column('member', sqlalchemy.String(255), nullable=False), sqlalchemy.Column('can_share', sqlalchemy.Boolean(), nullable=False, default=False), sqlalchemy.Column('created_at', sqlalchemy.DateTime(), nullable=False), sqlalchemy.Column('updated_at', sqlalchemy.DateTime()), sqlalchemy.Column('deleted_at', sqlalchemy.DateTime()), sqlalchemy.Column('deleted', sqlalchemy.Boolean(), nullable=False, default=False, index=True), sqlalchemy.UniqueConstraint('image_id', 'member'), extend_existing=True) image_properties_old = sqlalchemy.Table( 'image_properties_old', meta, sqlalchemy.Column('id', sqlalchemy.Integer(), primary_key=True, nullable=False), sqlalchemy.Column('image_id', sqlalchemy.Integer(), nullable=False, index=True), sqlalchemy.Column('name', sqlalchemy.String(255), nullable=False), sqlalchemy.Column('value', sqlalchemy.Text()), sqlalchemy.Column('created_at', sqlalchemy.DateTime(), nullable=False), sqlalchemy.Column('updated_at', sqlalchemy.DateTime()), sqlalchemy.Column('deleted_at', sqlalchemy.DateTime()), sqlalchemy.Column('deleted', sqlalchemy.Boolean(), nullable=False, default=False, index=True), sqlalchemy.UniqueConstraint( 'image_id', 'name', name='ix_image_properties_image_id_name'), extend_existing=True) image_members_old.create() image_properties_old.create() sql_commands = [ """INSERT INTO image_members_old SELECT * FROM image_members;""", """INSERT INTO image_properties_old SELECT * FROM image_properties;""", ] for command in sql_commands: meta.bind.execute(command) t_image_members.drop() t_image_properties.drop() image_members_old.rename(name='image_members') image_properties_old.rename(name='image_properties') def _downgrade_sqlite(t_images, t_image_members, t_image_properties): """ Downgrade 012 -> 011 with special SQLite-compatible logic. """ sql_commands = [ """CREATE TABLE images_backup ( id INTEGER NOT NULL, name VARCHAR(255), size INTEGER, status VARCHAR(30) NOT NULL, is_public BOOLEAN NOT NULL, location TEXT, created_at DATETIME NOT NULL, updated_at DATETIME, deleted_at DATETIME, deleted BOOLEAN NOT NULL, disk_format VARCHAR(20), container_format VARCHAR(20), checksum VARCHAR(32), owner VARCHAR(255), min_disk INTEGER NOT NULL, min_ram INTEGER NOT NULL, PRIMARY KEY (id), CHECK (is_public IN (0, 1)), CHECK (deleted IN (0, 1)) );""", """INSERT INTO images_backup SELECT * FROM images;""", """CREATE TABLE image_members_backup ( id INTEGER NOT NULL, image_id INTEGER NOT NULL, member VARCHAR(255) NOT NULL, can_share BOOLEAN NOT NULL, created_at DATETIME NOT NULL, updated_at DATETIME, deleted_at DATETIME, deleted BOOLEAN NOT NULL, PRIMARY KEY (id), UNIQUE (image_id, member), CHECK (can_share IN (0, 1)), CHECK (deleted IN (0, 1)), FOREIGN KEY(image_id) REFERENCES images (id) );""", """INSERT INTO image_members_backup SELECT * FROM image_members;""", """CREATE TABLE image_properties_backup ( id INTEGER NOT NULL, image_id INTEGER NOT NULL, name VARCHAR(255) NOT NULL, value TEXT, created_at DATETIME NOT NULL, updated_at DATETIME, deleted_at DATETIME, deleted BOOLEAN NOT NULL, PRIMARY KEY (id), CHECK (deleted IN (0, 1)), UNIQUE (image_id, name), FOREIGN KEY(image_id) REFERENCES images (id) );""", """INSERT INTO image_properties_backup SELECT * FROM image_properties;""", ] for command in sql_commands: meta.bind.execute(command) _sqlite_table_swap(t_image_members, t_image_properties, t_images) def _upgrade_other(t_images, t_image_members, t_image_properties, dialect): """ Upgrade 011 -> 012 with logic for non-SQLite databases. """ foreign_keys = _get_foreign_keys(t_images, t_image_members, t_image_properties, dialect) for fk in foreign_keys: fk.drop() t_images.c.id.alter(sqlalchemy.String(36), primary_key=True) t_image_members.c.image_id.alter(sqlalchemy.String(36)) t_image_properties.c.image_id.alter(sqlalchemy.String(36)) _update_all_ids_to_uuids(t_images, t_image_members, t_image_properties) for fk in foreign_keys: fk.create() def _downgrade_other(t_images, t_image_members, t_image_properties, dialect): """ Downgrade 012 -> 011 with logic for non-SQLite databases. """ foreign_keys = _get_foreign_keys(t_images, t_image_members, t_image_properties, dialect) for fk in foreign_keys: fk.drop() _update_all_uuids_to_ids(t_images, t_image_members, t_image_properties) t_images.c.id.alter(sqlalchemy.Integer(), primary_key=True) t_image_members.c.image_id.alter(sqlalchemy.Integer()) t_image_properties.c.image_id.alter(sqlalchemy.Integer()) for fk in foreign_keys: fk.create() def _sqlite_table_swap(t_image_members, t_image_properties, t_images): t_image_members.drop() t_image_properties.drop() t_images.drop() meta.bind.execute("ALTER TABLE images_backup " "RENAME TO images") meta.bind.execute("ALTER TABLE image_members_backup " "RENAME TO image_members") meta.bind.execute("ALTER TABLE image_properties_backup " "RENAME TO image_properties") meta.bind.execute("""CREATE INDEX ix_image_properties_deleted ON image_properties (deleted);""") meta.bind.execute("""CREATE INDEX ix_image_properties_name ON image_properties (name);""") def _get_table(table_name, metadata): """Return a sqlalchemy Table definition with associated metadata.""" return sqlalchemy.Table(table_name, metadata, autoload=True) def _get_foreign_keys(t_images, t_image_members, t_image_properties, dialect): """Retrieve and return foreign keys for members/properties tables.""" foreign_keys = [] if t_image_members.foreign_keys: img_members_fk_name = list(t_image_members.foreign_keys)[0].name if dialect == 'mysql': fk1 = migrate.ForeignKeyConstraint([t_image_members.c.image_id], [t_images.c.id], name=img_members_fk_name) else: fk1 = migrate.ForeignKeyConstraint([t_image_members.c.image_id], [t_images.c.id]) foreign_keys.append(fk1) if t_image_properties.foreign_keys: img_properties_fk_name = list(t_image_properties.foreign_keys)[0].name if dialect == 'mysql': fk2 = migrate.ForeignKeyConstraint([t_image_properties.c.image_id], [t_images.c.id], name=img_properties_fk_name) else: fk2 = migrate.ForeignKeyConstraint([t_image_properties.c.image_id], [t_images.c.id]) foreign_keys.append(fk2) return foreign_keys def _update_all_ids_to_uuids(t_images, t_image_members, t_image_properties): """Transition from INTEGER id to VARCHAR(36) id.""" images = list(t_images.select().execute()) for image in images: old_id = image["id"] new_id = str(uuid.uuid4()) t_images.update().\ where(t_images.c.id == old_id).\ values(id=new_id).execute() t_image_members.update().\ where(t_image_members.c.image_id == old_id).\ values(image_id=new_id).execute() t_image_properties.update().\ where(t_image_properties.c.image_id == old_id).\ values(image_id=new_id).execute() t_image_properties.update().\ where(and_(or_(t_image_properties.c.name == 'kernel_id', t_image_properties.c.name == 'ramdisk_id'), t_image_properties.c.value == old_id)).\ values(value=new_id).execute() def _update_all_uuids_to_ids(t_images, t_image_members, t_image_properties): """Transition from VARCHAR(36) id to INTEGER id.""" images = list(t_images.select().execute()) new_id = 1 for image in images: old_id = image["id"] t_images.update().\ where(t_images.c.id == old_id).\ values(id=str(new_id)).execute() t_image_members.update().\ where(t_image_members.c.image_id == old_id).\ values(image_id=str(new_id)).execute() t_image_properties.update().\ where(t_image_properties.c.image_id == old_id).\ values(image_id=str(new_id)).execute() t_image_properties.update().\ where(and_(or_(t_image_properties.c.name == 'kernel_id', t_image_properties.c.name == 'ramdisk_id'), t_image_properties.c.value == old_id)).\ values(value=str(new_id)).execute() new_id += 1 glance-2014.1/glance/db/sqlalchemy/migrate_repo/versions/008_add_image_members_table.py0000664000175400017540000000662212323736226032225 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from migrate.changeset import * # noqa from sqlalchemy import * # noqa from glance.db.sqlalchemy.migrate_repo.schema import ( Boolean, DateTime, Integer, String, create_tables, drop_tables, from_migration_import) # noqa def get_images_table(meta): """ No changes to the images table from 007... """ (get_images_table,) = from_migration_import( '007_add_owner', ['get_images_table']) images = get_images_table(meta) return images def get_image_properties_table(meta): """ No changes to the image properties table from 007... """ (get_image_properties_table,) = from_migration_import( '007_add_owner', ['get_image_properties_table']) image_properties = get_image_properties_table(meta) return image_properties def get_image_members_table(meta): images = get_images_table(meta) # noqa image_members = Table('image_members', meta, Column('id', Integer(), primary_key=True, nullable=False), Column('image_id', Integer(), ForeignKey('images.id'), nullable=False, index=True), Column('member', String(255), nullable=False), Column('can_share', Boolean(), nullable=False, default=False), Column('created_at', DateTime(), nullable=False), Column('updated_at', DateTime()), Column('deleted_at', DateTime()), Column('deleted', Boolean(), nullable=False, default=False, index=True), UniqueConstraint('image_id', 'member'), mysql_engine='InnoDB', extend_existing=True) # DB2: an index has already been created for the UniqueConstraint option # specified on the Table() statement above. if meta.bind.name != "ibm_db_sa": Index('ix_image_members_image_id_member', image_members.c.image_id, image_members.c.member) return image_members def upgrade(migrate_engine): meta = MetaData() meta.bind = migrate_engine tables = [get_image_members_table(meta)] create_tables(tables) def downgrade(migrate_engine): meta = MetaData() meta.bind = migrate_engine tables = [get_image_members_table(meta)] drop_tables(tables) glance-2014.1/glance/db/sqlalchemy/migrate_repo/versions/032_add_task_info_table.py0000664000175400017540000000614312323736226031401 0ustar jenkinsjenkins00000000000000# Copyright 2013 Rackspace # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from sqlalchemy.schema import (Column, ForeignKey, MetaData, Table) from glance.db.sqlalchemy.migrate_repo.schema import (String, Text, create_tables, drop_tables) # noqa TASKS_MIGRATE_COLUMNS = ['input', 'message', 'result'] def define_task_info_table(meta): Table('tasks', meta, autoload=True) #NOTE(nikhil): input and result are stored as text in the DB. # SQLAlchemy marshals the data to/from JSON using custom type # JSONEncodedDict. It uses simplejson underneath. task_info = Table('task_info', meta, Column('task_id', String(36), ForeignKey('tasks.id'), primary_key=True, nullable=False), Column('input', Text()), Column('result', Text()), Column('message', Text()), mysql_engine='InnoDB') return task_info def upgrade(migrate_engine): meta = MetaData() meta.bind = migrate_engine tables = [define_task_info_table(meta)] create_tables(tables) tasks_table = Table('tasks', meta, autoload=True) task_info_table = Table('task_info', meta, autoload=True) tasks = tasks_table.select().execute().fetchall() for task in tasks: values = { 'task_id': task.id, 'input': task.input, 'result': task.result, 'message': task.message, } task_info_table.insert(values=values).execute() for col_name in TASKS_MIGRATE_COLUMNS: tasks_table.columns[col_name].drop() def downgrade(migrate_engine): meta = MetaData() meta.bind = migrate_engine tasks_table = Table('tasks', meta, autoload=True) task_info_table = Table('task_info', meta, autoload=True) for col_name in TASKS_MIGRATE_COLUMNS: column = Column(col_name, Text()) column.create(tasks_table) task_info_records = task_info_table.select().execute().fetchall() for task_info in task_info_records: values = { 'input': task_info.input, 'result': task_info.result, 'message': task_info.message } tasks_table\ .update(values=values)\ .where(tasks_table.c.id == task_info.task_id)\ .execute() drop_tables([task_info_table]) glance-2014.1/glance/db/sqlalchemy/migrate_repo/versions/026_add_location_storage_information.py0000664000175400017540000000275212323736226034223 0ustar jenkinsjenkins00000000000000# Copyright 2013 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import sqlalchemy from glance.db.sqlalchemy.migrate_repo import schema def upgrade(migrate_engine): meta = sqlalchemy.schema.MetaData() meta.bind = migrate_engine image_locations_table = sqlalchemy.Table('image_locations', meta, autoload=True) meta_data = sqlalchemy.Column('meta_data', schema.PickleType(), default={}) meta_data.create(image_locations_table) def downgrade(migrate_engine): meta = sqlalchemy.schema.MetaData() meta.bind = migrate_engine image_locations_table = sqlalchemy.Table('image_locations', meta, autoload=True) image_locations_table.columns['meta_data'].drop() glance-2014.1/glance/db/sqlalchemy/migrate_repo/versions/017_quote_encrypted_swift_credentials.py0000664000175400017540000002060512323736226034452 0ustar jenkinsjenkins00000000000000# Copyright 2013 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ This migration handles migrating encrypted image location values from the unquoted form to the quoted form. If 'metadata_encryption_key' is specified in the config then this migration performs the following steps for every entry in the images table: 1. Decrypt the location value with the metadata_encryption_key 2. Changes the value to its quoted form 3. Encrypts the new value with the metadata_encryption_key 4. Inserts the new value back into the row Fixes bug #1081043 """ import types # noqa from oslo.config import cfg import six.moves.urllib.parse as urlparse import sqlalchemy from glance.common import crypt from glance.common import exception import glance.openstack.common.log as logging import glance.store.swift # noqa LOG = logging.getLogger(__name__) CONF = cfg.CONF CONF.import_opt('metadata_encryption_key', 'glance.common.config') def upgrade(migrate_engine): migrate_location_credentials(migrate_engine, to_quoted=True) def downgrade(migrate_engine): migrate_location_credentials(migrate_engine, to_quoted=False) def migrate_location_credentials(migrate_engine, to_quoted): """ Migrate location credentials for encrypted swift uri's between the quoted and unquoted forms. :param migrate_engine: The configured db engine :param to_quoted: If True, migrate location credentials from unquoted to quoted form. If False, do the reverse. """ if not CONF.metadata_encryption_key: msg = _("'metadata_encryption_key' was not specified in the config" " file or a config file was not specified. This means that" " this migration is a NOOP.") LOG.info(msg) return meta = sqlalchemy.schema.MetaData() meta.bind = migrate_engine images_table = sqlalchemy.Table('images', meta, autoload=True) images = list(images_table.select().execute()) for image in images: try: fixed_uri = fix_uri_credentials(image['location'], to_quoted) images_table.update()\ .where(images_table.c.id == image['id'])\ .values(location=fixed_uri).execute() except exception.Invalid: msg = _("Failed to decrypt location value for image %(image_id)s") LOG.warn(msg % {'image_id': image['id']}) except exception.BadStoreUri as e: err_msg = _("Invalid store uri for image: %(image_id)s. " "Details: %(reason)s") % {'image_id': image.id, 'reason': unicode(e)} LOG.exception(err_msg) raise def decrypt_location(uri): return crypt.urlsafe_decrypt(CONF.metadata_encryption_key, uri) def encrypt_location(uri): return crypt.urlsafe_encrypt(CONF.metadata_encryption_key, uri, 64) def fix_uri_credentials(uri, to_quoted): """ Fix the given uri's embedded credentials by round-tripping with StoreLocation. If to_quoted is True, the uri is assumed to have credentials that have not been quoted, and the resulting uri will contain quoted credentials. If to_quoted is False, the uri is assumed to have credentials that have been quoted, and the resulting uri will contain credentials that have not been quoted. """ if not uri: return try: decrypted_uri = decrypt_location(uri) #NOTE (ameade): If a uri is not encrypted or incorrectly encoded then we # we raise an exception. except (TypeError, ValueError) as e: raise exception.Invalid(str(e)) return legacy_parse_uri(decrypted_uri, to_quoted) def legacy_parse_uri(uri, to_quote): """ Parse URLs. This method fixes an issue where credentials specified in the URL are interpreted differently in Python 2.6.1+ than prior versions of Python. It also deals with the peculiarity that new-style Swift URIs have where a username can contain a ':', like so: swift://account:user:pass@authurl.com/container/obj If to_quoted is True, the uri is assumed to have credentials that have not been quoted, and the resulting uri will contain quoted credentials. If to_quoted is False, the uri is assumed to have credentials that have been quoted, and the resulting uri will contain credentials that have not been quoted. """ # Make sure that URIs that contain multiple schemes, such as: # swift://user:pass@http://authurl.com/v1/container/obj # are immediately rejected. if uri.count('://') != 1: reason = _("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") raise exception.BadStoreUri(message=reason) pieces = urlparse.urlparse(uri) assert pieces.scheme in ('swift', 'swift+http', 'swift+https') scheme = pieces.scheme netloc = pieces.netloc path = pieces.path.lstrip('/') if netloc != '': # > Python 2.6.1 if '@' in netloc: creds, netloc = netloc.split('@') else: creds = None else: # Python 2.6.1 compat # see lp659445 and Python issue7904 if '@' in path: creds, path = path.split('@') else: creds = None netloc = path[0:path.find('/')].strip('/') path = path[path.find('/'):].strip('/') if creds: cred_parts = creds.split(':') # User can be account:user, in which case cred_parts[0:2] will be # the account and user. Combine them into a single username of # account:user if to_quote: if len(cred_parts) == 1: reason = (_("Badly formed credentials '%(creds)s' in Swift " "URI") % {'creds': creds}) raise exception.BadStoreUri(message=reason) elif len(cred_parts) == 3: user = ':'.join(cred_parts[0:2]) else: user = cred_parts[0] key = cred_parts[-1] user = user key = key else: if len(cred_parts) != 2: reason = (_("Badly formed credentials in Swift URI.")) raise exception.BadStoreUri(message=reason) user, key = cred_parts user = urlparse.unquote(user) key = urlparse.unquote(key) else: user = None key = None path_parts = path.split('/') try: obj = path_parts.pop() container = path_parts.pop() if not netloc.startswith('http'): # push hostname back into the remaining to build full authurl path_parts.insert(0, netloc) auth_or_store_url = '/'.join(path_parts) except IndexError: reason = _("Badly formed S3 URI: %(uri)s") % {'uri': uri} raise exception.BadStoreUri(message=reason) if auth_or_store_url.startswith('http://'): auth_or_store_url = auth_or_store_url[len('http://'):] elif auth_or_store_url.startswith('https://'): auth_or_store_url = auth_or_store_url[len('https://'):] credstring = '' if user and key: if to_quote: quote_user = urlparse.quote(user) quote_key = urlparse.quote(key) else: quote_user = user quote_key = key credstring = '%s:%s@' % (quote_user, quote_key) auth_or_store_url = auth_or_store_url.strip('/') container = container.strip('/') obj = obj.strip('/') uri = '%s://%s%s/%s/%s' % (scheme, credstring, auth_or_store_url, container, obj) return encrypt_location(uri) glance-2014.1/glance/db/sqlalchemy/migrate_repo/versions/034_add_virtual_size.py0000664000175400017540000000220512323736226030772 0ustar jenkinsjenkins00000000000000# Copyright 2014 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. import sqlalchemy def upgrade(migrate_engine): meta = sqlalchemy.MetaData() meta.bind = migrate_engine images = sqlalchemy.Table('images', meta, autoload=True) virtual_size = sqlalchemy.Column('virtual_size', sqlalchemy.BigInteger) images.create_column(virtual_size) def downgrade(migrate_engine): meta = sqlalchemy.MetaData() meta.bind = migrate_engine images = sqlalchemy.Table('images', meta, autoload=True) images.columns['virtual_size'].drop() glance-2014.1/glance/db/sqlalchemy/migrate_repo/versions/028_owner_index.py0000664000175400017540000000216512323736226027773 0ustar jenkinsjenkins00000000000000# Copyright 2013 Rackspace Hosting # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from sqlalchemy import MetaData, Table, Index INDEX_NAME = 'owner_image_idx' def upgrade(migrate_engine): meta = MetaData() meta.bind = migrate_engine images = Table('images', meta, autoload=True) index = Index(INDEX_NAME, images.c.owner) index.create(migrate_engine) def downgrade(migrate_engine): meta = MetaData() meta.bind = migrate_engine images = Table('images', meta, autoload=True) index = Index(INDEX_NAME, images.c.owner) index.drop(migrate_engine) glance-2014.1/glance/db/sqlalchemy/migrate_repo/versions/015_quote_swift_credentials.py0000664000175400017540000001453512323736226032400 0ustar jenkinsjenkins00000000000000# Copyright 2012 OpenStack Foundation. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import six.moves.urllib.parse as urlparse import sqlalchemy from glance.common import exception import glance.openstack.common.log as logging LOG = logging.getLogger(__name__) def upgrade(migrate_engine): migrate_location_credentials(migrate_engine, to_quoted=True) def downgrade(migrate_engine): migrate_location_credentials(migrate_engine, to_quoted=False) def migrate_location_credentials(migrate_engine, to_quoted): """ Migrate location credentials for swift uri's between the quoted and unquoted forms. :param migrate_engine: The configured db engine :param to_quoted: If True, migrate location credentials from unquoted to quoted form. If False, do the reverse. """ meta = sqlalchemy.schema.MetaData() meta.bind = migrate_engine images_table = sqlalchemy.Table('images', meta, autoload=True) images = list(images_table.select(images_table.c.location.startswith( 'swift')).execute()) for image in images: try: fixed_uri = legacy_parse_uri(image['location'], to_quoted) images_table.update()\ .where(images_table.c.id == image['id'])\ .values(location=fixed_uri).execute() except exception.BadStoreUri as e: err_msg = _("Invalid store uri for image: %(image_id)s. " "Details: %(reason)s") % {'image_id': image.id, 'reason': unicode(e)} LOG.exception(err_msg) raise def legacy_parse_uri(uri, to_quote): """ Parse URLs. This method fixes an issue where credentials specified in the URL are interpreted differently in Python 2.6.1+ than prior versions of Python. It also deals with the peculiarity that new-style Swift URIs have where a username can contain a ':', like so: swift://account:user:pass@authurl.com/container/obj If to_quoted is True, the uri is assumed to have credentials that have not been quoted, and the resulting uri will contain quoted credentials. If to_quoted is False, the uri is assumed to have credentials that have been quoted, and the resulting uri will contain credentials that have not been quoted. """ # Make sure that URIs that contain multiple schemes, such as: # swift://user:pass@http://authurl.com/v1/container/obj # are immediately rejected. if uri.count('://') != 1: reason = _("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") raise exception.BadStoreUri(message=reason) pieces = urlparse.urlparse(uri) assert pieces.scheme in ('swift', 'swift+http', 'swift+https') scheme = pieces.scheme netloc = pieces.netloc path = pieces.path.lstrip('/') if netloc != '': # > Python 2.6.1 if '@' in netloc: creds, netloc = netloc.split('@') else: creds = None else: # Python 2.6.1 compat # see lp659445 and Python issue7904 if '@' in path: creds, path = path.split('@') else: creds = None netloc = path[0:path.find('/')].strip('/') path = path[path.find('/'):].strip('/') if creds: cred_parts = creds.split(':') # User can be account:user, in which case cred_parts[0:2] will be # the account and user. Combine them into a single username of # account:user if to_quote: if len(cred_parts) == 1: reason = (_("Badly formed credentials '%(creds)s' in Swift " "URI") % {'creds': creds}) raise exception.BadStoreUri(message=reason) elif len(cred_parts) == 3: user = ':'.join(cred_parts[0:2]) else: user = cred_parts[0] key = cred_parts[-1] user = user key = key else: if len(cred_parts) != 2: reason = (_("Badly formed credentials in Swift URI.")) raise exception.BadStoreUri(message=reason) user, key = cred_parts user = urlparse.unquote(user) key = urlparse.unquote(key) else: user = None key = None path_parts = path.split('/') try: obj = path_parts.pop() container = path_parts.pop() if not netloc.startswith('http'): # push hostname back into the remaining to build full authurl path_parts.insert(0, netloc) auth_or_store_url = '/'.join(path_parts) except IndexError: reason = _("Badly formed S3 URI: %(uri)s") % {'uri': uri} raise exception.BadStoreUri(message=reason) if auth_or_store_url.startswith('http://'): auth_or_store_url = auth_or_store_url[len('http://'):] elif auth_or_store_url.startswith('https://'): auth_or_store_url = auth_or_store_url[len('https://'):] credstring = '' if user and key: if to_quote: quote_user = urlparse.quote(user) quote_key = urlparse.quote(key) else: quote_user = user quote_key = key credstring = '%s:%s@' % (quote_user, quote_key) auth_or_store_url = auth_or_store_url.strip('/') container = container.strip('/') obj = obj.strip('/') return '%s://%s%s/%s/%s' % (scheme, credstring, auth_or_store_url, container, obj) glance-2014.1/glance/db/sqlalchemy/migrate_repo/versions/011_make_mindisk_and_minram_notnull.py0000664000175400017540000000212112323736226034025 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import sqlalchemy meta = sqlalchemy.MetaData() def upgrade(migrate_engine): meta.bind = migrate_engine images = sqlalchemy.Table('images', meta, autoload=True) images.c.min_disk.alter(nullable=False) images.c.min_ram.alter(nullable=False) def downgrade(migrate_engine): meta.bind = migrate_engine images = sqlalchemy.Table('images', meta, autoload=True) images.c.min_disk.alter(nullable=True) images.c.min_ram.alter(nullable=True) glance-2014.1/glance/db/sqlalchemy/migrate_repo/versions/014_add_image_tags_table.py0000664000175400017540000000566512323736226031534 0ustar jenkinsjenkins00000000000000# Copyright 2012 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from sqlalchemy import schema from glance.db.sqlalchemy.migrate_repo import schema as glance_schema def define_image_tags_table(meta): # Load the images table so the foreign key can be set up properly schema.Table('images', meta, autoload=True) image_tags = schema.Table('image_tags', meta, schema.Column('id', glance_schema.Integer(), primary_key=True, nullable=False), schema.Column('image_id', glance_schema.String(36), schema.ForeignKey('images.id'), nullable=False), schema.Column('value', glance_schema.String(255), nullable=False), schema.Column('created_at', glance_schema.DateTime(), nullable=False), schema.Column('updated_at', glance_schema.DateTime()), schema.Column('deleted_at', glance_schema.DateTime()), schema.Column('deleted', glance_schema.Boolean(), nullable=False, default=False), mysql_engine='InnoDB') schema.Index('ix_image_tags_image_id', image_tags.c.image_id) schema.Index('ix_image_tags_image_id_tag_value', image_tags.c.image_id, image_tags.c.value) return image_tags def upgrade(migrate_engine): meta = schema.MetaData() meta.bind = migrate_engine tables = [define_image_tags_table(meta)] glance_schema.create_tables(tables) def downgrade(migrate_engine): meta = schema.MetaData() meta.bind = migrate_engine tables = [define_image_tags_table(meta)] glance_schema.drop_tables(tables) glance-2014.1/glance/db/sqlalchemy/migrate_repo/versions/023_placeholder.py0000664000175400017540000000135612323736226027730 0ustar jenkinsjenkins00000000000000# Copyright 2013 OpenStack Foundation # Copyright 2013 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. def upgrade(migrate_engine): pass def downgrade(migration_engine): pass glance-2014.1/glance/db/sqlalchemy/migrate_repo/versions/011_sqlite_downgrade.sql0000664000175400017540000000324012323736226031137 0ustar jenkinsjenkins00000000000000BEGIN TRANSACTION; CREATE TEMPORARY TABLE images_backup ( id INTEGER NOT NULL, name VARCHAR(255), size INTEGER, status VARCHAR(30) NOT NULL, is_public BOOLEAN NOT NULL, location TEXT, created_at DATETIME NOT NULL, updated_at DATETIME, deleted_at DATETIME, deleted BOOLEAN NOT NULL, disk_format VARCHAR(20), container_format VARCHAR(20), checksum VARCHAR(32), owner VARCHAR(255), min_disk INTEGER NOT NULL, min_ram INTEGER NOT NULL, PRIMARY KEY (id), CHECK (is_public IN (0, 1)), CHECK (deleted IN (0, 1)) ); INSERT INTO images_backup SELECT id, name, size, status, is_public, location, created_at, updated_at, deleted_at, deleted, disk_format, container_format, checksum, owner, min_disk, min_ram FROM images; DROP TABLE images; CREATE TABLE images ( id INTEGER NOT NULL, name VARCHAR(255), size INTEGER, status VARCHAR(30) NOT NULL, is_public BOOLEAN NOT NULL, location TEXT, created_at DATETIME NOT NULL, updated_at DATETIME, deleted_at DATETIME, deleted BOOLEAN NOT NULL, disk_format VARCHAR(20), container_format VARCHAR(20), checksum VARCHAR(32), owner VARCHAR(255), min_disk INTEGER, min_ram INTEGER, PRIMARY KEY (id), CHECK (is_public IN (0, 1)), CHECK (deleted IN (0, 1)) ); CREATE INDEX ix_images_deleted ON images (deleted); CREATE INDEX ix_images_is_public ON images (is_public); INSERT INTO images SELECT id, name, size, status, is_public, location, created_at, updated_at, deleted_at, deleted, disk_format, container_format, checksum, owner, min_disk, min_ram FROM images_backup; DROP TABLE images_backup; COMMIT; glance-2014.1/glance/db/sqlalchemy/migrate_repo/versions/030_add_tasks_table.py0000664000175400017540000000452212323736226030546 0ustar jenkinsjenkins00000000000000# Copyright 2013 OpenStack Foundation # All Rights Reserved. # Copyright 2013 IBM Corp. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from sqlalchemy.schema import (Column, MetaData, Table, Index) from glance.db.sqlalchemy.migrate_repo.schema import ( Boolean, DateTime, String, Text, create_tables, drop_tables) # noqa def define_tasks_table(meta): tasks = Table('tasks', meta, Column('id', String(36), primary_key=True, nullable=False), Column('type', String(30), nullable=False), Column('status', String(30), nullable=False), Column('owner', String(255), nullable=False), Column('input', Text()), # json blob Column('result', Text()), # json blob Column('message', Text()), Column('expires_at', DateTime(), nullable=True), Column('created_at', DateTime(), nullable=False), Column('updated_at', DateTime()), Column('deleted_at', DateTime()), Column('deleted', Boolean(), nullable=False, default=False), mysql_engine='InnoDB', extend_existing=True) Index('ix_tasks_type', tasks.c.type) Index('ix_tasks_status', tasks.c.status) Index('ix_tasks_owner', tasks.c.owner) Index('ix_tasks_deleted', tasks.c.deleted) Index('ix_tasks_updated_at', tasks.c.updated_at) return tasks def upgrade(migrate_engine): meta = MetaData() meta.bind = migrate_engine tables = [define_tasks_table(meta)] create_tables(tables) def downgrade(migrate_engine): meta = MetaData() meta.bind = migrate_engine tables = [define_tasks_table(meta)] drop_tables(tables) glance-2014.1/glance/db/sqlalchemy/migrate_repo/versions/006_mysql_upgrade.sql0000664000175400017540000000055112323736226030466 0ustar jenkinsjenkins00000000000000/* * This file is necessary because MySQL does not support * renaming indexes. */ DROP INDEX ix_image_properties_image_id_key ON image_properties; /* Rename the `key` column to `name` */ ALTER TABLE image_properties CHANGE COLUMN `key` name VARCHAR(255) NOT NULL; CREATE UNIQUE INDEX ix_image_properties_image_id_name ON image_properties (image_id, name); glance-2014.1/glance/db/sqlalchemy/migrate_repo/versions/013_sqlite_downgrade.sql0000664000175400017540000000325712323736226031151 0ustar jenkinsjenkins00000000000000/* * This is necessary because sqlalchemy has various bugs preventing * downgrades from working correctly. */ BEGIN TRANSACTION; CREATE TEMPORARY TABLE images_backup ( id VARCHAR(36) NOT NULL, name VARCHAR(255), size INTEGER, status VARCHAR(30) NOT NULL, is_public BOOLEAN NOT NULL, location TEXT, created_at DATETIME NOT NULL, updated_at DATETIME, deleted_at DATETIME, deleted BOOLEAN NOT NULL, disk_format VARCHAR(20), container_format VARCHAR(20), checksum VARCHAR(32), owner VARCHAR(255), min_disk INTEGER NOT NULL, min_ram INTEGER NOT NULL, PRIMARY KEY (id), CHECK (is_public IN (0, 1)), CHECK (deleted IN (0, 1)) ); INSERT INTO images_backup SELECT id, name, size, status, is_public, location, created_at, updated_at, deleted_at, deleted, disk_format, container_format, checksum, owner, min_disk, min_ram FROM images; DROP TABLE images; CREATE TABLE images ( id VARCHAR(36) NOT NULL, name VARCHAR(255), size INTEGER, status VARCHAR(30) NOT NULL, is_public BOOLEAN NOT NULL, location TEXT, created_at DATETIME NOT NULL, updated_at DATETIME, deleted_at DATETIME, deleted BOOLEAN NOT NULL, disk_format VARCHAR(20), container_format VARCHAR(20), checksum VARCHAR(32), owner VARCHAR(255), min_disk INTEGER NOT NULL, min_ram INTEGER NOT NULL, PRIMARY KEY (id), CHECK (is_public IN (0, 1)), CHECK (deleted IN (0, 1)) ); CREATE INDEX ix_images_is_public ON images (is_public); CREATE INDEX ix_images_deleted ON images (deleted); INSERT INTO images SELECT id, name, size, status, is_public, location, created_at, updated_at, deleted_at, deleted, disk_format, container_format, checksum, owner, min_disk, min_ram FROM images_backup; DROP TABLE images_backup; COMMIT; glance-2014.1/glance/db/sqlalchemy/migrate_repo/versions/025_placeholder.py0000664000175400017540000000135612323736226027732 0ustar jenkinsjenkins00000000000000# Copyright 2013 OpenStack Foundation # Copyright 2013 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. def upgrade(migrate_engine): pass def downgrade(migration_engine): pass glance-2014.1/glance/db/sqlalchemy/migrate_repo/versions/022_image_member_index.py0000664000175400017540000000677212323736226031254 0ustar jenkinsjenkins00000000000000# Copyright 2013 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. import re from migrate.changeset import UniqueConstraint from sqlalchemy import and_, func, orm from sqlalchemy import MetaData, Table from sqlalchemy.exc import OperationalError, ProgrammingError NEW_KEYNAME = 'image_members_image_id_member_deleted_at_key' ORIGINAL_KEYNAME_RE = re.compile('image_members_image_id.*_key') def upgrade(migrate_engine): image_members = _get_image_members_table(migrate_engine) if (migrate_engine.name == 'mysql' or migrate_engine.name == 'postgresql'): try: UniqueConstraint('image_id', name=_get_original_keyname(migrate_engine.name), table=image_members).drop() except (OperationalError, ProgrammingError): UniqueConstraint('image_id', name=_infer_original_keyname(image_members), table=image_members).drop() UniqueConstraint('image_id', 'member', 'deleted_at', name=NEW_KEYNAME, table=image_members).create() def downgrade(migrate_engine): image_members = _get_image_members_table(migrate_engine) if (migrate_engine.name == 'mysql' or migrate_engine.name == 'postgresql'): _sanitize(migrate_engine, image_members) UniqueConstraint('image_id', name=NEW_KEYNAME, table=image_members).drop() UniqueConstraint('image_id', 'member', name=_get_original_keyname(migrate_engine.name), table=image_members).create() def _get_image_members_table(migrate_engine): meta = MetaData() meta.bind = migrate_engine return Table('image_members', meta, autoload=True) def _get_original_keyname(db): return {'mysql': 'image_id', 'postgresql': 'image_members_image_id_member_key'}[db] def _infer_original_keyname(table): for i in table.indexes: if ORIGINAL_KEYNAME_RE.match(i.name): return i.name def _sanitize(migrate_engine, table): """ Avoid possible integrity error by removing deleted rows to accommdate less restrictive uniqueness constraint """ session = orm.sessionmaker(bind=migrate_engine)() # find the image_member rows containing duplicate combinations # of image_id and member qry = (session.query(table.c.image_id, table.c.member) .group_by(table.c.image_id, table.c.member) .having(func.count() > 1)) for image_id, member in qry: # only remove duplicate rows already marked deleted d = table.delete().where(and_(table.c.deleted == True, table.c.image_id == image_id, table.c.member == member)) d.execute() session.close() glance-2014.1/glance/db/sqlalchemy/migrate_repo/versions/010_default_update_at.py0000664000175400017540000000457012323736226031115 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from migrate.changeset import * # noqa from sqlalchemy import * # noqa from glance.db.sqlalchemy.migrate_repo.schema import from_migration_import def get_images_table(meta): """ No changes to the images table from 008... """ (get_images_table,) = from_migration_import( '008_add_image_members_table', ['get_images_table']) images = get_images_table(meta) return images def get_image_properties_table(meta): """ No changes to the image properties table from 008... """ (get_image_properties_table,) = from_migration_import( '008_add_image_members_table', ['get_image_properties_table']) image_properties = get_image_properties_table(meta) return image_properties def get_image_members_table(meta): """ No changes to the image members table from 008... """ (get_image_members_table,) = from_migration_import( '008_add_image_members_table', ['get_image_members_table']) images = get_image_members_table(meta) return images def upgrade(migrate_engine): meta = MetaData() meta.bind = migrate_engine images_table = get_images_table(meta) # set updated_at to created_at if equal to None conn = migrate_engine.connect() conn.execute( images_table.update( images_table.c.updated_at == None, {images_table.c.updated_at: images_table.c.created_at})) def downgrade(migrate_engine): meta = MetaData() meta.bind = migrate_engine images_table = get_images_table(meta) # set updated_at to None if equal to created_at conn = migrate_engine.connect() conn.execute( images_table.update( images_table.c.updated_at == images_table.c.created_at, {images_table.c.updated_at: None})) glance-2014.1/glance/db/sqlalchemy/migrate_repo/versions/006_sqlite_upgrade.sql0000664000175400017540000000242412323736226030623 0ustar jenkinsjenkins00000000000000/* * This is necessary because SQLite does not support * RENAME INDEX or ALTER TABLE CHANGE COLUMN. */ BEGIN TRANSACTION; CREATE TEMPORARY TABLE image_properties_backup ( id INTEGER NOT NULL, image_id INTEGER NOT NULL, name VARCHAR(255) NOT NULL, value TEXT, created_at DATETIME NOT NULL, updated_at DATETIME, deleted_at DATETIME, deleted BOOLEAN NOT NULL, PRIMARY KEY (id) ); INSERT INTO image_properties_backup SELECT id, image_id, key, value, created_at, updated_at, deleted_at, deleted FROM image_properties; DROP TABLE image_properties; CREATE TABLE image_properties ( id INTEGER NOT NULL, image_id INTEGER NOT NULL, name VARCHAR(255) NOT NULL, value TEXT, created_at DATETIME NOT NULL, updated_at DATETIME, deleted_at DATETIME, deleted BOOLEAN NOT NULL, PRIMARY KEY (id), CHECK (deleted IN (0, 1)), UNIQUE (image_id, name), FOREIGN KEY(image_id) REFERENCES images (id) ); CREATE INDEX ix_image_properties_name ON image_properties (name); CREATE INDEX ix_image_properties_deleted ON image_properties (deleted); INSERT INTO image_properties (id, image_id, name, value, created_at, updated_at, deleted_at, deleted) SELECT id, image_id, name, value, created_at, updated_at, deleted_at, deleted FROM image_properties_backup; DROP TABLE image_properties_backup; COMMIT; glance-2014.1/glance/db/sqlalchemy/migrate_repo/versions/029_location_meta_data_pickle_to_string.py0000664000175400017540000000510212323736226034673 0ustar jenkinsjenkins00000000000000# Copyright 2013 Rackspace Hosting # 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 json import pickle import sqlalchemy from sqlalchemy import MetaData, Table, Column # noqa from glance.db.sqlalchemy import models def upgrade(migrate_engine): meta = sqlalchemy.schema.MetaData(migrate_engine) image_locations = Table('image_locations', meta, autoload=True) new_meta_data = Column('storage_meta_data', models.JSONEncodedDict, default={}) new_meta_data.create(image_locations) noe = pickle.dumps({}) s = sqlalchemy.sql.select([image_locations]).\ where(image_locations.c.meta_data != noe) conn = migrate_engine.connect() res = conn.execute(s) for row in res: meta_data = row['meta_data'] x = pickle.loads(meta_data) if x != {}: stmt = image_locations.update().\ where(image_locations.c.id == row['id']).\ values(storage_meta_data=x) conn.execute(stmt) conn.close() image_locations.columns['meta_data'].drop() image_locations.columns['storage_meta_data'].alter(name='meta_data') def downgrade(migrate_engine): meta = sqlalchemy.schema.MetaData(migrate_engine) image_locations = Table('image_locations', meta, autoload=True) old_meta_data = Column('old_meta_data', sqlalchemy.PickleType(), default={}) old_meta_data.create(image_locations) noj = json.dumps({}) s = sqlalchemy.sql.select([image_locations]).\ where(image_locations.c.meta_data != noj) conn = migrate_engine.connect() res = conn.execute(s) for row in res: x = row['meta_data'] meta_data = json.loads(x) if meta_data != {}: stmt = image_locations.update().\ where(image_locations.c.id == row['id']).\ values(old_meta_data=meta_data) conn.execute(stmt) conn.close() image_locations.columns['meta_data'].drop() image_locations.columns['old_meta_data'].alter(name='meta_data') glance-2014.1/glance/db/sqlalchemy/migrate_repo/versions/003_sqlite_downgrade.sql0000664000175400017540000000307112323736226031142 0ustar jenkinsjenkins00000000000000BEGIN; /* Make changes to the base images table */ CREATE TEMPORARY TABLE images_backup ( id INTEGER NOT NULL, name VARCHAR(255), size INTEGER, status VARCHAR(30) NOT NULL, is_public BOOLEAN NOT NULL, location TEXT, created_at DATETIME NOT NULL, updated_at DATETIME, deleted_at DATETIME, deleted BOOLEAN NOT NULL, PRIMARY KEY (id) ); INSERT INTO images_backup SELECT id, name, size, status, is_public, location, created_at, updated_at, deleted_at, deleted FROM images; DROP TABLE images; CREATE TABLE images ( id INTEGER NOT NULL, name VARCHAR(255), size INTEGER, type VARCHAR(30), status VARCHAR(30) NOT NULL, is_public BOOLEAN NOT NULL, location TEXT, created_at DATETIME NOT NULL, updated_at DATETIME, deleted_at DATETIME, deleted BOOLEAN NOT NULL, PRIMARY KEY (id), CHECK (is_public IN (0, 1)), CHECK (deleted IN (0, 1)) ); CREATE INDEX ix_images_deleted ON images (deleted); CREATE INDEX ix_images_is_public ON images (is_public); INSERT INTO images (id, name, size, status, is_public, location, created_at, updated_at, deleted_at, deleted) SELECT id, name, size, status, is_public, location, created_at, updated_at, deleted_at, deleted FROM images_backup; DROP TABLE images_backup; /* Re-insert the type values from the temp table */ UPDATE images SET type = (SELECT value FROM image_properties WHERE image_id = images.id AND key = 'type') WHERE EXISTS (SELECT * FROM image_properties WHERE image_id = images.id AND key = 'type'); /* Remove the type properties from the image_properties table */ DELETE FROM image_properties WHERE key = 'type'; COMMIT; glance-2014.1/glance/db/sqlalchemy/migrate_repo/versions/006_key_to_name.py0000664000175400017540000001164512323736226027743 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from migrate.changeset import * # noqa from sqlalchemy import * # noqa from glance.db.sqlalchemy.migrate_repo.schema import ( Boolean, DateTime, Integer, String, Text, from_migration_import) # noqa def get_images_table(meta): """ No changes to the image properties table from 002... """ (get_images_table,) = from_migration_import( '004_add_checksum', ['get_images_table']) images = get_images_table(meta) return images def get_image_properties_table(meta): """ Returns the Table object for the image_properties table that corresponds to the image_properties table definition of this version. """ (get_images_table,) = from_migration_import( '004_add_checksum', ['get_images_table']) images = get_images_table(meta) # noqa image_properties = Table('image_properties', meta, Column('id', Integer(), primary_key=True, nullable=False), Column('image_id', Integer(), ForeignKey('images.id'), nullable=False, index=True), Column('name', String(255), nullable=False), Column('value', Text()), Column('created_at', DateTime(), nullable=False), Column('updated_at', DateTime()), Column('deleted_at', DateTime()), Column('deleted', Boolean(), nullable=False, default=False, index=True), UniqueConstraint('image_id', 'name'), mysql_engine='InnoDB', extend_existing=True) return image_properties def upgrade(migrate_engine): meta = MetaData() meta.bind = migrate_engine (get_image_properties_table,) = from_migration_import( '004_add_checksum', ['get_image_properties_table']) image_properties = get_image_properties_table(meta) if migrate_engine.name == "ibm_db_sa": # NOTE(dperaza) ibm db2 does not allow ALTER INDEX so we will drop # the index, rename the column, then re-create the index sql_commands = [ """ALTER TABLE image_properties DROP UNIQUE ix_image_properties_image_id_key;""", """ALTER TABLE image_properties RENAME COLUMN \"key\" to name;""", """ALTER TABLE image_properties ADD CONSTRAINT ix_image_properties_image_id_name UNIQUE(image_id, name);""", ] for command in sql_commands: meta.bind.execute(command) else: index = Index('ix_image_properties_image_id_key', image_properties.c.image_id, image_properties.c.key) index.rename('ix_image_properties_image_id_name') image_properties = get_image_properties_table(meta) image_properties.columns['key'].alter(name="name") def downgrade(migrate_engine): meta = MetaData() meta.bind = migrate_engine image_properties = get_image_properties_table(meta) if migrate_engine.name == "ibm_db_sa": # NOTE(dperaza) ibm db2 does not allow ALTER INDEX so we will drop # the index, rename the column, then re-create the index sql_commands = [ """ALTER TABLE image_properties DROP UNIQUE ix_image_properties_image_id_name;""", """ALTER TABLE image_properties RENAME COLUMN name to \"key\";""", """ALTER TABLE image_properties ADD CONSTRAINT ix_image_properties_image_id_key UNIQUE(image_id, \"key\");""", ] for command in sql_commands: meta.bind.execute(command) else: index = Index('ix_image_properties_image_id_name', image_properties.c.image_id, image_properties.c.name) index.rename('ix_image_properties_image_id_key') image_properties.columns['name'].alter(name="key") glance-2014.1/glance/db/sqlalchemy/migrate_repo/versions/016_add_status_image_member.py0000664000175400017540000000211712323736226032270 0ustar jenkinsjenkins00000000000000# Copyright 2013 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from sqlalchemy import MetaData, Table, Column, String meta = MetaData() status = Column('status', String(20), default="pending") def upgrade(migrate_engine): meta.bind = migrate_engine image_members = Table('image_members', meta, autoload=True) image_members.create_column(status) def downgrade(migrate_engine): meta.bind = migrate_engine image_members = Table('image_members', meta, autoload=True) image_members.drop_column(status) glance-2014.1/glance/db/sqlalchemy/migrate_repo/versions/018_add_image_locations_table.py0000664000175400017540000000442712323736226032570 0ustar jenkinsjenkins00000000000000# Copyright 2013 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import sqlalchemy from glance.db.sqlalchemy.migrate_repo import schema def upgrade(migrate_engine): meta = sqlalchemy.schema.MetaData(migrate_engine) #NOTE(bcwaldon): load the images table for the ForeignKey below sqlalchemy.Table('images', meta, autoload=True) image_locations_table = sqlalchemy.Table( 'image_locations', meta, sqlalchemy.Column('id', schema.Integer(), primary_key=True, nullable=False), sqlalchemy.Column('image_id', schema.String(36), sqlalchemy.ForeignKey('images.id'), nullable=False, index=True), sqlalchemy.Column('value', schema.Text(), nullable=False), sqlalchemy.Column('created_at', schema.DateTime(), nullable=False), sqlalchemy.Column('updated_at', schema.DateTime()), sqlalchemy.Column('deleted_at', schema.DateTime()), sqlalchemy.Column('deleted', schema.Boolean(), nullable=False, default=False, index=True), ) schema.create_tables([image_locations_table]) def downgrade(migrate_engine): meta = sqlalchemy.schema.MetaData(migrate_engine) image_locations_table = sqlalchemy.Table('image_locations', meta, autoload=True) schema.drop_tables([image_locations_table]) glance-2014.1/glance/db/sqlalchemy/migrate_repo/versions/002_add_image_properties_table.py0000664000175400017540000000650712323736226032763 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from sqlalchemy.schema import ( Column, ForeignKey, Index, MetaData, Table, UniqueConstraint) from glance.db.sqlalchemy.migrate_repo.schema import ( Boolean, DateTime, Integer, String, Text, create_tables, drop_tables, from_migration_import) # noqa def define_image_properties_table(meta): (define_images_table,) = from_migration_import( '001_add_images_table', ['define_images_table']) images = define_images_table(meta) # noqa # NOTE(dperaza) DB2: specify the UniqueConstraint option when creating the # table will cause an index being created to specify the index # name and skip the step of creating another index with the same columns. # The index name is needed so it can be dropped and re-created later on. constr_kwargs = {} if meta.bind.name == 'ibm_db_sa': constr_kwargs['name'] = 'ix_image_properties_image_id_key' image_properties = Table('image_properties', meta, Column('id', Integer(), primary_key=True, nullable=False), Column('image_id', Integer(), ForeignKey('images.id'), nullable=False, index=True), Column('key', String(255), nullable=False), Column('value', Text()), Column('created_at', DateTime(), nullable=False), Column('updated_at', DateTime()), Column('deleted_at', DateTime()), Column('deleted', Boolean(), nullable=False, default=False, index=True), UniqueConstraint('image_id', 'key', **constr_kwargs), mysql_engine='InnoDB', extend_existing=True) if meta.bind.name != 'ibm_db_sa': Index('ix_image_properties_image_id_key', image_properties.c.image_id, image_properties.c.key) return image_properties def upgrade(migrate_engine): meta = MetaData() meta.bind = migrate_engine tables = [define_image_properties_table(meta)] create_tables(tables) def downgrade(migrate_engine): meta = MetaData() meta.bind = migrate_engine tables = [define_image_properties_table(meta)] drop_tables(tables) glance-2014.1/glance/db/sqlalchemy/migrate_repo/versions/011_sqlite_upgrade.sql0000664000175400017540000000323412323736226030617 0ustar jenkinsjenkins00000000000000BEGIN TRANSACTION; CREATE TEMPORARY TABLE images_backup ( id INTEGER NOT NULL, name VARCHAR(255), size INTEGER, status VARCHAR(30) NOT NULL, is_public BOOLEAN NOT NULL, location TEXT, created_at DATETIME NOT NULL, updated_at DATETIME, deleted_at DATETIME, deleted BOOLEAN NOT NULL, disk_format VARCHAR(20), container_format VARCHAR(20), checksum VARCHAR(32), owner VARCHAR(255), min_disk INTEGER, min_ram INTEGER, PRIMARY KEY (id), CHECK (is_public IN (0, 1)), CHECK (deleted IN (0, 1)) ); INSERT INTO images_backup SELECT id, name, size, status, is_public, location, created_at, updated_at, deleted_at, deleted, disk_format, container_format, checksum, owner, min_disk, min_ram FROM images; DROP TABLE images; CREATE TABLE images ( id INTEGER NOT NULL, name VARCHAR(255), size INTEGER, status VARCHAR(30) NOT NULL, is_public BOOLEAN NOT NULL, location TEXT, created_at DATETIME NOT NULL, updated_at DATETIME, deleted_at DATETIME, deleted BOOLEAN NOT NULL, disk_format VARCHAR(20), container_format VARCHAR(20), checksum VARCHAR(32), owner VARCHAR(255), min_disk INTEGER NOT NULL, min_ram INTEGER NOT NULL, PRIMARY KEY (id), CHECK (is_public IN (0, 1)), CHECK (deleted IN (0, 1)) ); CREATE INDEX ix_images_deleted ON images (deleted); CREATE INDEX ix_images_is_public ON images (is_public); INSERT INTO images SELECT id, name, size, status, is_public, location, created_at, updated_at, deleted_at, deleted, disk_format, container_format, checksum, owner, min_disk, min_ram FROM images_backup; DROP TABLE images_backup; COMMIT; glance-2014.1/glance/db/sqlalchemy/migrate_repo/versions/016_sqlite_downgrade.sql0000664000175400017540000000235712323736226031154 0ustar jenkinsjenkins00000000000000BEGIN TRANSACTION; CREATE TEMPORARY TABLE image_members_backup ( id INTEGER NOT NULL, image_id VARCHAR(36) NOT NULL, member VARCHAR(255) NOT NULL, can_share BOOLEAN NOT NULL, created_at DATETIME NOT NULL, updated_at DATETIME, deleted_at DATETIME, deleted BOOLEAN NOT NULL, PRIMARY KEY (id), UNIQUE (image_id, member), CHECK (can_share IN (0, 1)), CHECK (deleted IN (0, 1)), FOREIGN KEY(image_id) REFERENCES images (id) ); INSERT INTO image_members_backup SELECT id, image_id, member, can_share, created_at, updated_at, deleted_at, deleted FROM image_members; DROP TABLE image_members; CREATE TABLE image_members ( id INTEGER NOT NULL, image_id VARCHAR(36) NOT NULL, member VARCHAR(255) NOT NULL, can_share BOOLEAN NOT NULL, created_at DATETIME NOT NULL, updated_at DATETIME, deleted_at DATETIME, deleted BOOLEAN NOT NULL, PRIMARY KEY (id), UNIQUE (image_id, member), CHECK (can_share IN (0, 1)), CHECK (deleted IN (0, 1)), FOREIGN KEY(image_id) REFERENCES images (id) ); INSERT INTO image_members SELECT id, image_id, member, can_share, created_at, updated_at, deleted_at, deleted FROM image_members_backup; DROP TABLE image_members_backup; COMMIT; glance-2014.1/glance/db/sqlalchemy/migrate_repo/versions/004_add_checksum.py0000664000175400017540000000547612323736226030066 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from migrate.changeset import * # noqa from sqlalchemy import * # noqa from glance.db.sqlalchemy.migrate_repo.schema import ( Boolean, DateTime, Integer, String, Text, from_migration_import) # noqa def get_images_table(meta): """ Returns the Table object for the images table that corresponds to the images table definition of this version. """ images = Table('images', meta, Column('id', Integer(), primary_key=True, nullable=False), Column('name', String(255)), Column('disk_format', String(20)), Column('container_format', String(20)), Column('size', Integer()), Column('status', String(30), nullable=False), Column('is_public', Boolean(), nullable=False, default=False, index=True), Column('location', Text()), Column('created_at', DateTime(), nullable=False), Column('updated_at', DateTime()), Column('deleted_at', DateTime()), Column('deleted', Boolean(), nullable=False, default=False, index=True), Column('checksum', String(32)), mysql_engine='InnoDB', extend_existing=True) return images def get_image_properties_table(meta): """ No changes to the image properties table from 002... """ (define_image_properties_table,) = from_migration_import( '002_add_image_properties_table', ['define_image_properties_table']) image_properties = define_image_properties_table(meta) return image_properties def upgrade(migrate_engine): meta = MetaData() meta.bind = migrate_engine images = get_images_table(meta) checksum = Column('checksum', String(32)) checksum.create(images) def downgrade(migrate_engine): meta = MetaData() meta.bind = migrate_engine images = get_images_table(meta) images.columns['checksum'].drop() glance-2014.1/glance/db/sqlalchemy/migrate_repo/versions/020_drop_images_table_location.py0000664000175400017540000000224712323736226032773 0ustar jenkinsjenkins00000000000000# Copyright 2013 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import sqlalchemy from glance.db.sqlalchemy.migrate_repo import schema def get_images_table(meta): return sqlalchemy.Table('images', meta, autoload=True) def upgrade(migrate_engine): meta = sqlalchemy.schema.MetaData(migrate_engine) images_table = get_images_table(meta) images_table.columns['location'].drop() def downgrade(migrate_engine): meta = sqlalchemy.schema.MetaData(migrate_engine) images_table = get_images_table(meta) location = sqlalchemy.Column('location', schema.Text()) location.create(images_table) glance-2014.1/glance/db/sqlalchemy/migrate_repo/versions/013_add_protected.py0000664000175400017540000000205312323736226030241 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from sqlalchemy import MetaData, Table, Column, Boolean meta = MetaData() protected = Column('protected', Boolean, default=False) def upgrade(migrate_engine): meta.bind = migrate_engine images = Table('images', meta, autoload=True) images.create_column(protected) def downgrade(migrate_engine): meta.bind = migrate_engine images = Table('images', meta, autoload=True) images.drop_column(protected) glance-2014.1/glance/db/sqlalchemy/migrate_repo/versions/033_add_location_status.py0000664000175400017540000000377312323736226031477 0ustar jenkinsjenkins00000000000000# Copyright 2014 IBM Corp. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import sqlalchemy from glance.db.sqlalchemy.migrate_repo import schema def upgrade(migrate_engine): meta = sqlalchemy.schema.MetaData() meta.bind = migrate_engine images_table = sqlalchemy.Table('images', meta, autoload=True) image_locations_table = sqlalchemy.Table('image_locations', meta, autoload=True) # Create 'status' column for image_locations table status = sqlalchemy.Column('status', schema.String(30), server_default='active', nullable=False) status.create(image_locations_table) # Set 'status' column initial value for image_locations table mapping = {'active': 'active', 'pending_delete': 'pending_delete', 'deleted': 'deleted', 'killed': 'deleted'} for src, dst in mapping.iteritems(): subq = sqlalchemy.sql.select([images_table.c.id])\ .where(images_table.c.status == src) image_locations_table.update(values={'status': dst})\ .where(image_locations_table.c.image_id.in_(subq))\ .execute() def downgrade(migrate_engine): meta = sqlalchemy.schema.MetaData() meta.bind = migrate_engine image_locations_table = sqlalchemy.Table('image_locations', meta, autoload=True) # Remove 'status' column from image_locations table image_locations_table.columns['status'].drop() glance-2014.1/glance/db/sqlalchemy/migrate_repo/versions/007_add_owner.py0000664000175400017540000000553712323736226027417 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from migrate.changeset import * # noqa from sqlalchemy import * # noqa from glance.db.sqlalchemy.migrate_repo.schema import ( Boolean, DateTime, BigInteger, Integer, String, Text, from_migration_import) # noqa def get_images_table(meta): """ Returns the Table object for the images table that corresponds to the images table definition of this version. """ images = Table('images', meta, Column('id', Integer(), primary_key=True, nullable=False), Column('name', String(255)), Column('disk_format', String(20)), Column('container_format', String(20)), Column('size', BigInteger()), Column('status', String(30), nullable=False), Column('is_public', Boolean(), nullable=False, default=False, index=True), Column('location', Text()), Column('created_at', DateTime(), nullable=False), Column('updated_at', DateTime()), Column('deleted_at', DateTime()), Column('deleted', Boolean(), nullable=False, default=False, index=True), Column('checksum', String(32)), Column('owner', String(255)), mysql_engine='InnoDB', extend_existing=True) return images def get_image_properties_table(meta): """ No changes to the image properties table from 006... """ (get_image_properties_table,) = from_migration_import( '006_key_to_name', ['get_image_properties_table']) image_properties = get_image_properties_table(meta) return image_properties def upgrade(migrate_engine): meta = MetaData() meta.bind = migrate_engine images = get_images_table(meta) owner = Column('owner', String(255)) owner.create(images) def downgrade(migrate_engine): meta = MetaData() meta.bind = migrate_engine images = get_images_table(meta) images.columns['owner'].drop() glance-2014.1/glance/db/sqlalchemy/migrate_repo/versions/009_add_mindisk_and_minram.py0000664000175400017540000000614612323736226032107 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from migrate.changeset import * # noqa from sqlalchemy import * # noqa from glance.db.sqlalchemy.migrate_repo.schema import ( Boolean, DateTime, Integer, String, Text, from_migration_import) # noqa def get_images_table(meta): """ Returns the Table object for the images table that corresponds to the images table definition of this version. """ images = Table('images', meta, Column('id', Integer(), primary_key=True, nullable=False), Column('name', String(255)), Column('disk_format', String(20)), Column('container_format', String(20)), Column('size', Integer()), Column('status', String(30), nullable=False), Column('is_public', Boolean(), nullable=False, default=False, index=True), Column('location', Text()), Column('created_at', DateTime(), nullable=False), Column('updated_at', DateTime()), Column('deleted_at', DateTime()), Column('deleted', Boolean(), nullable=False, default=False, index=True), Column('checksum', String(32)), Column('owner', String(255)), Column('min_disk', Integer(), default=0), Column('min_ram', Integer(), default=0), mysql_engine='InnoDB', extend_existing=True) return images def get_image_properties_table(meta): """ No changes to the image properties table from 008... """ (define_image_properties_table,) = from_migration_import( '008_add_image_members_table', ['define_image_properties_table']) image_properties = define_image_properties_table(meta) return image_properties def upgrade(migrate_engine): meta = MetaData() meta.bind = migrate_engine images = get_images_table(meta) min_disk = Column('min_disk', Integer(), default=0) min_disk.create(images) min_ram = Column('min_ram', Integer(), default=0) min_ram.create(images) def downgrade(migrate_engine): meta = MetaData() meta.bind = migrate_engine images = get_images_table(meta) images.columns['min_disk'].drop() images.columns['min_ram'].drop() glance-2014.1/glance/db/sqlalchemy/migrate_repo/versions/003_add_disk_format.py0000664000175400017540000001306312323736226030554 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from migrate.changeset import * # noqa from sqlalchemy import * # noqa from glance.db.sqlalchemy.migrate_repo.schema import ( Boolean, DateTime, Integer, String, Text, from_migration_import) # noqa def get_images_table(meta): """ Returns the Table object for the images table that corresponds to the images table definition of this version. """ images = Table('images', meta, Column('id', Integer(), primary_key=True, nullable=False), Column('name', String(255)), Column('disk_format', String(20)), Column('container_format', String(20)), Column('size', Integer()), Column('status', String(30), nullable=False), Column('is_public', Boolean(), nullable=False, default=False, index=True), Column('location', Text()), Column('created_at', DateTime(), nullable=False), Column('updated_at', DateTime()), Column('deleted_at', DateTime()), Column('deleted', Boolean(), nullable=False, default=False, index=True), mysql_engine='InnoDB', extend_existing=True) return images def get_image_properties_table(meta): """ No changes to the image properties table from 002... """ (define_image_properties_table,) = from_migration_import( '002_add_image_properties_table', ['define_image_properties_table']) image_properties = define_image_properties_table(meta) return image_properties def upgrade(migrate_engine): meta = MetaData() meta.bind = migrate_engine (define_images_table,) = from_migration_import( '001_add_images_table', ['define_images_table']) (define_image_properties_table,) = from_migration_import( '002_add_image_properties_table', ['define_image_properties_table']) conn = migrate_engine.connect() images = define_images_table(meta) image_properties = define_image_properties_table(meta) # Steps to take, in this order: # 1) Move the existing type column from Image into # ImageProperty for all image records that have a non-NULL # type column # 2) Drop the type column in images # 3) Add the new columns to images # The below wackiness correlates to the following ANSI SQL: # SELECT images.* FROM images # LEFT JOIN image_properties # ON images.id = image_properties.image_id # AND image_properties.key = 'type' # WHERE image_properties.image_id IS NULL # AND images.type IS NOT NULL # # which returns all the images that have a type set # but that DO NOT yet have an image_property record # with key of type. from_stmt = [ images.outerjoin(image_properties, and_(images.c.id == image_properties.c.image_id, image_properties.c.key == 'type')) ] and_stmt = and_(image_properties.c.image_id == None, images.c.type != None) sel = select([images], from_obj=from_stmt).where(and_stmt) image_records = conn.execute(sel).fetchall() property_insert = image_properties.insert() for record in image_records: conn.execute(property_insert, image_id=record.id, key='type', created_at=record.created_at, deleted=False, value=record.type) conn.close() disk_format = Column('disk_format', String(20)) disk_format.create(images) container_format = Column('container_format', String(20)) container_format.create(images) images.columns['type'].drop() def downgrade(migrate_engine): meta = MetaData() meta.bind = migrate_engine # Steps to take, in this order: # 1) Add type column back to Image # 2) Move the existing type properties from ImageProperty into # Image.type # 3) Drop the disk_format and container_format columns in Image conn = migrate_engine.connect() images = get_images_table(meta) image_properties = get_image_properties_table(meta) type_col = Column('type', String(30)) type_col.create(images) sel = select([image_properties]).where(image_properties.c.key == 'type') type_property_records = conn.execute(sel).fetchall() for record in type_property_records: upd = images.update().where( images.c.id == record.image_id).values(type=record.value) conn.execute(upd) dlt = image_properties.delete().where( image_properties.c.image_id == record.image_id) conn.execute(dlt) conn.close() images.columns['disk_format'].drop() images.columns['container_format'].drop() glance-2014.1/glance/db/sqlalchemy/migrate_repo/versions/006_sqlite_downgrade.sql0000664000175400017540000000230612323736226031145 0ustar jenkinsjenkins00000000000000/* * This is necessary because SQLite does not support * RENAME INDEX or ALTER TABLE CHANGE COLUMN. */ BEGIN TRANSACTION; CREATE TEMPORARY TABLE image_properties_backup ( id INTEGER NOT NULL, image_id INTEGER NOT NULL, key VARCHAR(255) NOT NULL, value TEXT, created_at DATETIME NOT NULL, updated_at DATETIME, deleted_at DATETIME, deleted BOOLEAN NOT NULL, PRIMARY KEY (id) ); INSERT INTO image_properties_backup SELECT id, image_id, name, value, created_at, updated_at, deleted_at, deleted FROM image_properties; DROP TABLE image_properties; CREATE TABLE image_properties ( id INTEGER NOT NULL, image_id INTEGER NOT NULL, key VARCHAR(255) NOT NULL, value TEXT, created_at DATETIME NOT NULL, updated_at DATETIME, deleted_at DATETIME, deleted BOOLEAN NOT NULL, PRIMARY KEY (id), CHECK (deleted IN (0, 1)), UNIQUE (image_id, key), FOREIGN KEY(image_id) REFERENCES images (id) ); CREATE INDEX ix_image_properties_key ON image_properties (key); INSERT INTO image_properties (id, image_id, key, value, created_at, updated_at, deleted_at, deleted) SELECT id, image_id, key, value, created_at, updated_at, deleted_at, deleted FROM image_properties_backup; DROP TABLE image_properties_backup; COMMIT; glance-2014.1/glance/db/sqlalchemy/migrate_repo/versions/024_placeholder.py0000664000175400017540000000135612323736226027731 0ustar jenkinsjenkins00000000000000# Copyright 2013 OpenStack Foundation # Copyright 2013 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. def upgrade(migrate_engine): pass def downgrade(migration_engine): pass glance-2014.1/glance/db/sqlalchemy/migrate_repo/versions/001_add_images_table.py0000664000175400017540000000425512323736226030667 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from sqlalchemy.schema import (Column, MetaData, Table) from glance.db.sqlalchemy.migrate_repo.schema import ( Boolean, DateTime, Integer, String, Text, create_tables, drop_tables) # noqa def define_images_table(meta): images = Table('images', meta, Column('id', Integer(), primary_key=True, nullable=False), Column('name', String(255)), Column('type', String(30)), Column('size', Integer()), Column('status', String(30), nullable=False), Column('is_public', Boolean(), nullable=False, default=False, index=True), Column('location', Text()), Column('created_at', DateTime(), nullable=False), Column('updated_at', DateTime()), Column('deleted_at', DateTime()), Column('deleted', Boolean(), nullable=False, default=False, index=True), mysql_engine='InnoDB', extend_existing=True) return images def upgrade(migrate_engine): meta = MetaData() meta.bind = migrate_engine tables = [define_images_table(meta)] create_tables(tables) def downgrade(migrate_engine): meta = MetaData() meta.bind = migrate_engine tables = [define_images_table(meta)] drop_tables(tables) glance-2014.1/glance/db/sqlalchemy/migrate_repo/versions/__init__.py0000664000175400017540000000005612323736226026615 0ustar jenkinsjenkins00000000000000# template repository default versions module glance-2014.1/glance/db/sqlalchemy/migrate_repo/versions/003_sqlite_upgrade.sql0000664000175400017540000000325212323736226030620 0ustar jenkinsjenkins00000000000000BEGIN TRANSACTION; /* Move type column from base images table * to be records in image_properties table */ CREATE TEMPORARY TABLE tmp_type_records (id INTEGER NOT NULL, type VARCHAR(30) NOT NULL); INSERT INTO tmp_type_records SELECT id, type FROM images WHERE type IS NOT NULL; REPLACE INTO image_properties (image_id, key, value, created_at, deleted) SELECT id, 'type', type, date('now'), 0 FROM tmp_type_records; DROP TABLE tmp_type_records; /* Make changes to the base images table */ CREATE TEMPORARY TABLE images_backup ( id INTEGER NOT NULL, name VARCHAR(255), size INTEGER, status VARCHAR(30) NOT NULL, is_public BOOLEAN NOT NULL, location TEXT, created_at DATETIME NOT NULL, updated_at DATETIME, deleted_at DATETIME, deleted BOOLEAN NOT NULL, PRIMARY KEY (id) ); INSERT INTO images_backup SELECT id, name, size, status, is_public, location, created_at, updated_at, deleted_at, deleted FROM images; DROP TABLE images; CREATE TABLE images ( id INTEGER NOT NULL, name VARCHAR(255), size INTEGER, status VARCHAR(30) NOT NULL, is_public BOOLEAN NOT NULL, location TEXT, created_at DATETIME NOT NULL, updated_at DATETIME, deleted_at DATETIME, deleted BOOLEAN NOT NULL, disk_format VARCHAR(20), container_format VARCHAR(20), PRIMARY KEY (id), CHECK (is_public IN (0, 1)), CHECK (deleted IN (0, 1)) ); CREATE INDEX ix_images_deleted ON images (deleted); CREATE INDEX ix_images_is_public ON images (is_public); INSERT INTO images (id, name, size, status, is_public, location, created_at, updated_at, deleted_at, deleted) SELECT id, name, size, status, is_public, location, created_at, updated_at, deleted_at, deleted FROM images_backup; DROP TABLE images_backup; COMMIT; glance-2014.1/glance/db/sqlalchemy/migrate_repo/manage.py0000664000175400017540000000141212323736226024433 0ustar jenkinsjenkins00000000000000#!/usr/bin/env python # Copyright (c) 2012 OpenStack Foundation # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # implied. # See the License for the specific language governing permissions and # limitations under the License. from migrate.versioning.shell import main # This should probably be a console script entry point. if __name__ == '__main__': main(debug='False', repository='.') glance-2014.1/glance/db/sqlalchemy/migrate_repo/schema.py0000664000175400017540000000616012323736226024450 0ustar jenkinsjenkins00000000000000# Copyright 2011 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ Various conveniences used for migration scripts """ import sqlalchemy.types import glance.openstack.common.log as logging LOG = logging.getLogger(__name__) String = lambda length: sqlalchemy.types.String( length=length, convert_unicode=False, unicode_error=None, _warn_on_bytestring=False) Text = lambda: sqlalchemy.types.Text( length=None, convert_unicode=False, unicode_error=None, _warn_on_bytestring=False) Boolean = lambda: sqlalchemy.types.Boolean(create_constraint=True, name=None) DateTime = lambda: sqlalchemy.types.DateTime(timezone=False) Integer = lambda: sqlalchemy.types.Integer() BigInteger = lambda: sqlalchemy.types.BigInteger() PickleType = lambda: sqlalchemy.types.PickleType() def from_migration_import(module_name, fromlist): """ Import a migration file and return the module :param module_name: name of migration module to import from (ex: 001_add_images_table) :param fromlist: list of items to import (ex: define_images_table) :retval: module object This bit of ugliness warrants an explanation: As you're writing migrations, you'll frequently want to refer to tables defined in previous migrations. In the interest of not repeating yourself, you need a way of importing that table into a 'future' migration. However, tables are bound to metadata, so what you need to import is really a table factory, which you can late-bind to your current metadata object. Moreover, migrations begin with a number (001...), which means they aren't valid Python identifiers. This means we can't perform a 'normal' import on them (the Python lexer will 'splode). Instead, we need to use __import__ magic to bring the table-factory into our namespace. Example Usage: (define_images_table,) = from_migration_import( '001_add_images_table', ['define_images_table']) images = define_images_table(meta) # Refer to images table """ module_path = 'glance.db.sqlalchemy.migrate_repo.versions.%s' % module_name module = __import__(module_path, globals(), locals(), fromlist, -1) return [getattr(module, item) for item in fromlist] def create_tables(tables): for table in tables: LOG.info(_("creating table %(table)s") % {'table': table}) table.create() def drop_tables(tables): for table in tables: LOG.info(_("dropping table %(table)s") % {'table': table}) table.drop() glance-2014.1/glance/db/sqlalchemy/migrate_repo/README0000664000175400017540000000015312323736226023512 0ustar jenkinsjenkins00000000000000This is a database migration repository. More information at http://code.google.com/p/sqlalchemy-migrate/ glance-2014.1/glance/db/sqlalchemy/migrate_repo/migrate.cfg0000664000175400017540000000174112323736226024747 0ustar jenkinsjenkins00000000000000[db_settings] # Used to identify which repository this database is versioned under. # You can use the name of your project. repository_id=Glance Migrations # The name of the database table used to track the schema version. # This name shouldn't already be used by your project. # If this is changed once a database is under version control, you'll need to # change the table name in each database too. version_table=migrate_version # When committing a change script, Migrate will attempt to generate the # sql for all supported databases; normally, if one of them fails - probably # because you don't have that database installed - it is ignored and the # commit continues, perhaps ending successfully. # Databases in this list MUST compile successfully during a commit, or the # entire commit will fail. List the databases your application will actually # be using to ensure your updates to that database work properly. # This must be a list; example: ['postgres','sqlite'] required_dbs=[] glance-2014.1/glance/db/sqlalchemy/migrate_repo/__init__.py0000664000175400017540000000004512323736226024743 0ustar jenkinsjenkins00000000000000# template repository default module glance-2014.1/glance/db/sqlalchemy/__init__.py0000664000175400017540000000000012323736226022255 0ustar jenkinsjenkins00000000000000glance-2014.1/glance/db/simple/0000775000175400017540000000000012323736427017310 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/db/simple/api.py0000664000175400017540000006602712323736226020443 0ustar jenkinsjenkins00000000000000# Copyright 2012 OpenStack, Foundation # Copyright 2013 IBM Corp. # 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 copy import functools import uuid from glance.common import exception import glance.openstack.common.log as logging from glance.openstack.common import timeutils LOG = logging.getLogger(__name__) DATA = { 'images': {}, 'members': {}, 'tags': {}, 'locations': [], 'tasks': {}, 'task_info': {} } def log_call(func): @functools.wraps(func) def wrapped(*args, **kwargs): LOG.info(_('Calling %(funcname)s: args=%(args)s, kwargs=%(kwargs)s') % {"funcname": func.__name__, "args": args, "kwargs": kwargs}) output = func(*args, **kwargs) LOG.info(_('Returning %(funcname)s: %(output)s') % {"funcname": func.__name__, "output": output}) return output return wrapped def reset(): global DATA DATA = { 'images': {}, 'members': [], 'tags': {}, 'locations': [], 'tasks': {}, 'task_info': {} } def clear_db_env(*args, **kwargs): """ Setup global environment configuration variables. We have no connection-oriented environment variables, so this is a NOOP. """ pass def _get_session(): return DATA def _image_locations_format(image_id, value, meta_data): dt = timeutils.utcnow() return { 'id': str(uuid.uuid4()), 'image_id': image_id, 'created_at': dt, 'updated_at': dt, 'deleted_at': None, 'deleted': False, 'url': value, 'metadata': meta_data, } def _image_property_format(image_id, name, value): return { 'image_id': image_id, 'name': name, 'value': value, 'deleted': False, 'deleted_at': None, } def _image_member_format(image_id, tenant_id, can_share, status='pending'): dt = timeutils.utcnow() return { 'id': str(uuid.uuid4()), 'image_id': image_id, 'member': tenant_id, 'can_share': can_share, 'status': status, 'created_at': dt, 'updated_at': dt, } def _pop_task_info_values(values): task_info_values = {} for k, v in values.items(): if k in ['input', 'result', 'message']: values.pop(k) task_info_values[k] = v return task_info_values def _format_task_from_db(task_ref, task_info_ref): task = copy.deepcopy(task_ref) if task_info_ref: task_info = copy.deepcopy(task_info_ref) task_info_values = _pop_task_info_values(task_info) task.update(task_info_values) return task def _task_format(task_id, **values): dt = timeutils.utcnow() task = { 'id': task_id, 'type': 'import', 'status': 'pending', 'owner': None, 'expires_at': None, 'created_at': dt, 'updated_at': dt, 'deleted_at': None, 'deleted': False, } task.update(values) return task def _task_info_format(task_id, **values): task_info = { 'task_id': task_id, 'input': None, 'result': None, 'message': None, } task_info.update(values) return task_info def _image_format(image_id, **values): dt = timeutils.utcnow() image = { 'id': image_id, 'name': None, 'owner': None, 'locations': [], 'status': 'queued', 'protected': False, 'is_public': False, 'container_format': None, 'disk_format': None, 'min_ram': 0, 'min_disk': 0, 'size': None, 'virtual_size': None, 'checksum': None, 'tags': [], 'created_at': dt, 'updated_at': dt, 'deleted_at': None, 'deleted': False, } locations = values.pop('locations', None) if locations is not None: locations = [ _image_locations_format(image_id, location['url'], location['metadata']) for location in locations ] image['locations'] = locations #NOTE(bcwaldon): store properties as a list to match sqlalchemy driver properties = values.pop('properties', {}) properties = [{'name': k, 'value': v, 'image_id': image_id, 'deleted': False} for k, v in properties.items()] image['properties'] = properties image.update(values) return image def _filter_images(images, filters, context, status='accepted', is_public=None, admin_as_user=False): filtered_images = [] if 'properties' in filters: prop_filter = filters.pop('properties') filters.update(prop_filter) if status == 'all': status = None visibility = filters.pop('visibility', None) for image in images: member = image_member_find(context, image_id=image['id'], member=context.owner, status=status) is_member = len(member) > 0 has_ownership = context.owner and image['owner'] == context.owner can_see = (image['is_public'] or has_ownership or is_member or (context.is_admin and not admin_as_user)) if not can_see: continue if visibility: if visibility == 'public': if not image['is_public']: continue elif visibility == 'private': if image['is_public']: continue if not (has_ownership or (context.is_admin and not admin_as_user)): continue elif visibility == 'shared': if not is_member: continue if is_public is not None: if not image['is_public'] == is_public: continue to_add = True for k, value in filters.iteritems(): key = k if k.endswith('_min') or k.endswith('_max'): key = key[0:-4] try: value = int(value) except ValueError: msg = _("Unable to filter on a range " "with a non-numeric value.") raise exception.InvalidFilterRangeValue(msg) if k.endswith('_min'): to_add = image.get(key) >= value elif k.endswith('_max'): to_add = image.get(key) <= value elif k != 'is_public' and image.get(k) is not None: to_add = image.get(key) == value elif k == 'tags': filter_tags = value image_tags = image_tag_get_all(context, image['id']) for tag in filter_tags: if tag not in image_tags: to_add = False break else: to_add = False for p in image['properties']: properties = {p['name']: p['value'], 'deleted': p['deleted']} to_add |= (properties.get(key) == value and properties.get('deleted') is False) if not to_add: break if to_add: filtered_images.append(image) return filtered_images def _do_pagination(context, images, marker, limit, show_deleted, status='accepted'): start = 0 end = -1 if marker is None: start = 0 else: # Check that the image is accessible _image_get(context, marker, force_show_deleted=show_deleted, status=status) for i, image in enumerate(images): if image['id'] == marker: start = i + 1 break else: raise exception.NotFound() end = start + limit if limit is not None else None return images[start:end] def _sort_images(images, sort_key, sort_dir): reverse = False if images and not (sort_key in images[0]): raise exception.InvalidSortKey() keyfn = lambda x: (x[sort_key] if x[sort_key] is not None else '', x['created_at'], x['id']) reverse = sort_dir == 'desc' images.sort(key=keyfn, reverse=reverse) return images def _image_get(context, image_id, force_show_deleted=False, status=None): try: image = DATA['images'][image_id] image['locations'] = _image_location_get_all(image_id) except KeyError: LOG.info(_('Could not find image %s') % image_id) raise exception.NotFound() if image['deleted'] and not (force_show_deleted or context.show_deleted): LOG.info(_('Unable to get deleted image')) raise exception.NotFound() if not is_image_visible(context, image): LOG.info(_('Unable to get unowned image')) raise exception.Forbidden("Image not visible to you") return image @log_call def image_get(context, image_id, session=None, force_show_deleted=False): image = _image_get(context, image_id, force_show_deleted) image = _normalize_locations(image) return copy.deepcopy(image) @log_call def image_get_all(context, filters=None, marker=None, limit=None, sort_key='created_at', sort_dir='desc', member_status='accepted', is_public=None, admin_as_user=False): filters = filters or {} images = DATA['images'].values() images = _filter_images(images, filters, context, member_status, is_public, admin_as_user) images = _sort_images(images, sort_key, sort_dir) images = _do_pagination(context, images, marker, limit, filters.get('deleted')) for image in images: image['locations'] = _image_location_get_all(image['id']) _normalize_locations(image) return images @log_call def image_property_create(context, values): image = _image_get(context, values['image_id']) prop = _image_property_format(values['image_id'], values['name'], values['value']) image['properties'].append(prop) return prop @log_call def image_property_delete(context, prop_ref, image_ref, session=None): prop = None for p in DATA['images'][image_ref]['properties']: if p['name'] == prop_ref: prop = p if not prop: raise exception.NotFound() prop['deleted_at'] = timeutils.utcnow() prop['deleted'] = True return prop @log_call def image_member_find(context, image_id=None, member=None, status=None): filters = [] images = DATA['images'] members = DATA['members'] def is_visible(member): return (member['member'] == context.owner or images[member['image_id']]['owner'] == context.owner) if not context.is_admin: filters.append(is_visible) if image_id is not None: filters.append(lambda m: m['image_id'] == image_id) if member is not None: filters.append(lambda m: m['member'] == member) if status is not None: filters.append(lambda m: m['status'] == status) for f in filters: members = filter(f, members) return [copy.deepcopy(m) for m in members] @log_call def image_member_count(context, image_id): """Return the number of image members for this image :param image_id: identifier of image entity """ if not image_id: msg = _("Image id is required.") raise exception.Invalid(msg) members = DATA['members'] return len(filter(lambda x: x['image_id'] == image_id, members)) @log_call def image_member_create(context, values): member = _image_member_format(values['image_id'], values['member'], values.get('can_share', False), values.get('status', 'pending')) global DATA DATA['members'].append(member) return copy.deepcopy(member) @log_call def image_member_update(context, member_id, values): global DATA for member in DATA['members']: if (member['id'] == member_id): member.update(values) member['updated_at'] = timeutils.utcnow() return copy.deepcopy(member) else: raise exception.NotFound() @log_call def image_member_delete(context, member_id): global DATA for i, member in enumerate(DATA['members']): if (member['id'] == member_id): del DATA['members'][i] break else: raise exception.NotFound() def _image_locations_set(image_id, locations): global DATA image = DATA['images'][image_id] for location in image['locations']: location['deleted'] = True location['deleted_at'] = timeutils.utcnow() for i, location in enumerate(DATA['locations']): if image_id == location['image_id'] and location['deleted'] is False: del DATA['locations'][i] for location in locations: location_ref = _image_locations_format(image_id, value=location['url'], meta_data=location['metadata']) DATA['locations'].append(location_ref) image['locations'].append(location_ref) def _normalize_locations(image): undeleted_locations = filter(lambda x: not x['deleted'], image['locations']) image['locations'] = [{'url': loc['url'], 'metadata': loc['metadata']} for loc in undeleted_locations] return image def _image_location_get_all(image_id): location_data = [] for location in DATA['locations']: if image_id == location['image_id']: location_data.append(location) return location_data @log_call def image_create(context, image_values): global DATA image_id = image_values.get('id', str(uuid.uuid4())) if image_id in DATA['images']: raise exception.Duplicate() if 'status' not in image_values: raise exception.Invalid('status is a required attribute') allowed_keys = set(['id', 'name', 'status', 'min_ram', 'min_disk', 'size', 'virtual_size', 'checksum', 'locations', 'owner', 'protected', 'is_public', 'container_format', 'disk_format', 'created_at', 'updated_at', 'deleted', 'deleted_at', 'properties', 'tags']) incorrect_keys = set(image_values.keys()) - allowed_keys if incorrect_keys: raise exception.Invalid( 'The keys %s are not valid' % str(incorrect_keys)) image = _image_format(image_id, **image_values) DATA['images'][image_id] = image location_data = image_values.get('locations') if location_data is not None: _image_locations_set(image_id, location_data) DATA['tags'][image_id] = image.pop('tags', []) return _normalize_locations(copy.deepcopy(image)) @log_call def image_update(context, image_id, image_values, purge_props=False, from_state=None): global DATA try: image = DATA['images'][image_id] except KeyError: raise exception.NotFound() location_data = image_values.pop('locations', None) if location_data is not None: _image_locations_set(image_id, location_data) # replace values for properties that already exist new_properties = image_values.pop('properties', {}) for prop in image['properties']: if prop['name'] in new_properties: prop['value'] = new_properties.pop(prop['name']) elif purge_props: # this matches weirdness in the sqlalchemy api prop['deleted'] = True # add in any completly new properties image['properties'].extend([{'name': k, 'value': v, 'image_id': image_id, 'deleted': False} for k, v in new_properties.items()]) image['updated_at'] = timeutils.utcnow() image.update(image_values) DATA['images'][image_id] = image return _normalize_locations(image) @log_call def image_destroy(context, image_id): global DATA try: DATA['images'][image_id]['deleted'] = True DATA['images'][image_id]['deleted_at'] = timeutils.utcnow() # NOTE(flaper87): Move the image to one of the deleted statuses # if it hasn't been done yet. if (DATA['images'][image_id]['status'] not in ['deleted', 'pending_delete']): DATA['images'][image_id]['status'] = 'deleted' _image_locations_set(image_id, []) for prop in DATA['images'][image_id]['properties']: image_property_delete(context, prop['name'], image_id) members = image_member_find(context, image_id=image_id) for member in members: image_member_delete(context, member['id']) tags = image_tag_get_all(context, image_id) for tag in tags: image_tag_delete(context, image_id, tag) _normalize_locations(DATA['images'][image_id]) return copy.deepcopy(DATA['images'][image_id]) except KeyError: raise exception.NotFound() @log_call def image_tag_get_all(context, image_id): return DATA['tags'].get(image_id, []) @log_call def image_tag_get(context, image_id, value): tags = image_tag_get_all(context, image_id) if value in tags: return value else: raise exception.NotFound() @log_call def image_tag_set_all(context, image_id, values): global DATA DATA['tags'][image_id] = values @log_call def image_tag_create(context, image_id, value): global DATA DATA['tags'][image_id].append(value) return value @log_call def image_tag_delete(context, image_id, value): global DATA try: DATA['tags'][image_id].remove(value) except ValueError: raise exception.NotFound() def is_image_mutable(context, image): """Return True if the image is mutable in this context.""" # Is admin == image mutable if context.is_admin: return True # No owner == image not mutable if image['owner'] is None or context.owner is None: return False # Image only mutable by its owner return image['owner'] == context.owner def is_image_visible(context, image, status=None): """Return True if the image is visible in this context.""" # Is admin == image visible if context.is_admin: return True # No owner == image visible if image['owner'] is None: return True # Image is_public == image visible if image['is_public']: return True # Perform tests based on whether we have an owner if context.owner is not None: if context.owner == image['owner']: return True # Figure out if this image is shared with that tenant if status == 'all': status = None members = image_member_find(context, image_id=image['id'], member=context.owner, status=status) if members: return True # Private image return False def user_get_storage_usage(context, owner_id, image_id=None, session=None): images = image_get_all(context, filters={'owner': owner_id}) total = 0 for image in images: if image['status'] in ['killed', 'pending_delete', 'deleted']: continue if image['id'] != image_id: locations = [l for l in image['locations'] if not l.get('deleted', False)] total += (image['size'] * len(locations)) return total @log_call def task_create(context, values): """Create a task object""" global DATA task_values = copy.deepcopy(values) task_id = task_values.get('id', str(uuid.uuid4())) required_attributes = ['type', 'status', 'input'] allowed_attributes = ['id', 'type', 'status', 'input', 'result', 'owner', 'message', 'expires_at', 'created_at', 'updated_at', 'deleted_at', 'deleted'] if task_id in DATA['tasks']: raise exception.Duplicate() for key in required_attributes: if key not in task_values: raise exception.Invalid('%s is a required attribute' % key) incorrect_keys = set(task_values.keys()) - set(allowed_attributes) if incorrect_keys: raise exception.Invalid( 'The keys %s are not valid' % str(incorrect_keys)) task_info_values = _pop_task_info_values(task_values) task = _task_format(task_id, **task_values) DATA['tasks'][task_id] = task task_info = _task_info_create(task['id'], task_info_values) return _format_task_from_db(task, task_info) @log_call def task_update(context, task_id, values): """Update a task object""" global DATA task_values = copy.deepcopy(values) task_info_values = _pop_task_info_values(task_values) try: task = DATA['tasks'][task_id] except KeyError: msg = (_("No task found with ID %s") % task_id) LOG.debug(msg) raise exception.TaskNotFound(task_id=task_id) task.update(task_values) task['updated_at'] = timeutils.utcnow() DATA['tasks'][task_id] = task task_info = _task_info_update(task['id'], task_info_values) return _format_task_from_db(task, task_info) @log_call def task_get(context, task_id, force_show_deleted=False): task, task_info = _task_get(context, task_id, force_show_deleted) return _format_task_from_db(task, task_info) def _task_get(context, task_id, force_show_deleted=False): try: task = DATA['tasks'][task_id] except KeyError: msg = _('Could not find task %s') % task_id LOG.info(msg) raise exception.TaskNotFound(task_id=task_id) if task['deleted'] and not (force_show_deleted or context.show_deleted): msg = _('Unable to get deleted task %s') % task_id LOG.info(msg) raise exception.TaskNotFound(task_id=task_id) if not _is_task_visible(context, task): msg = (_("Forbidding request, task %s is not visible") % task_id) LOG.debug(msg) raise exception.Forbidden(msg) task_info = _task_info_get(task_id) return task, task_info @log_call def task_delete(context, task_id): global DATA try: DATA['tasks'][task_id]['deleted'] = True DATA['tasks'][task_id]['deleted_at'] = timeutils.utcnow() DATA['tasks'][task_id]['updated_at'] = timeutils.utcnow() return copy.deepcopy(DATA['tasks'][task_id]) except KeyError: msg = (_("No task found with ID %s") % task_id) LOG.debug(msg) raise exception.TaskNotFound(task_id=task_id) @log_call def task_get_all(context, filters=None, marker=None, limit=None, sort_key='created_at', sort_dir='desc'): """ Get all tasks that match zero or more filters. :param filters: dict of filter keys and values. :param marker: task id after which to start page :param limit: maximum number of tasks to return :param sort_key: task attribute by which results should be sorted :param sort_dir: direction in which results should be sorted (asc, desc) :return: tasks set """ filters = filters or {} tasks = DATA['tasks'].values() tasks = _filter_tasks(tasks, filters, context) tasks = _sort_tasks(tasks, sort_key, sort_dir) tasks = _paginate_tasks(context, tasks, marker, limit, filters.get('deleted')) filtered_tasks = [] for task in tasks: filtered_tasks.append(_format_task_from_db(task, task_info_ref=None)) return filtered_tasks def _is_task_visible(context, task): """Return True if the task is visible in this context.""" # Is admin == task visible if context.is_admin: return True # No owner == task visible if task['owner'] is None: return True # Perform tests based on whether we have an owner if context.owner is not None: if context.owner == task['owner']: return True return False def _filter_tasks(tasks, filters, context, admin_as_user=False): filtered_tasks = [] for task in tasks: has_ownership = context.owner and task['owner'] == context.owner can_see = (has_ownership or (context.is_admin and not admin_as_user)) if not can_see: continue add = True for k, value in filters.iteritems(): add = task[k] == value and task['deleted'] is False if not add: break if add: filtered_tasks.append(task) return filtered_tasks def _sort_tasks(tasks, sort_key, sort_dir): reverse = False if tasks and not (sort_key in tasks[0]): raise exception.InvalidSortKey() keyfn = lambda x: (x[sort_key] if x[sort_key] is not None else '', x['created_at'], x['id']) reverse = sort_dir == 'desc' tasks.sort(key=keyfn, reverse=reverse) return tasks def _paginate_tasks(context, tasks, marker, limit, show_deleted): start = 0 end = -1 if marker is None: start = 0 else: # Check that the task is accessible _task_get(context, marker, force_show_deleted=show_deleted) for i, task in enumerate(tasks): if task['id'] == marker: start = i + 1 break else: if task: raise exception.TaskNotFound(task_id=task['id']) else: msg = _("Task does not exist") raise exception.NotFound(message=msg) end = start + limit if limit is not None else None return tasks[start:end] def _task_info_create(task_id, values): """Create a Task Info for Task with given task ID""" global DATA task_info = _task_info_format(task_id, **values) DATA['task_info'][task_id] = task_info return task_info def _task_info_update(task_id, values): """Update Task Info for Task with given task ID and updated values""" global DATA try: task_info = DATA['task_info'][task_id] except KeyError: msg = (_("No task info found with task id %s") % task_id) LOG.debug(msg) raise exception.TaskNotFound(task_id=task_id) task_info.update(values) DATA['task_info'][task_id] = task_info return task_info def _task_info_get(task_id): """Get Task Info for Task with given task ID""" global DATA try: task_info = DATA['task_info'][task_id] except KeyError: msg = _('Could not find task info %s') % task_id LOG.info(msg) raise exception.TaskNotFound(task_id=task_id) return task_info glance-2014.1/glance/db/simple/__init__.py0000664000175400017540000000000012323736226021404 0ustar jenkinsjenkins00000000000000glance-2014.1/glance/db/registry/0000775000175400017540000000000012323736427017667 5ustar jenkinsjenkins00000000000000glance-2014.1/glance/db/registry/api.py0000664000175400017540000001640412323736226021014 0ustar jenkinsjenkins00000000000000# Copyright 2013 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. """ This is the Registry's Driver API. This API relies on the registry RPC client (version >= 2). The functions bellow work as a proxy for the database back-end configured in the registry service, which means that everything returned by that back-end will be also returned by this API. This API exists for supporting deployments not willing to put database credentials in glance-api. Those deployments can rely on this registry driver that will talk to a remote registry service, which will then access the database back-end. """ import functools import glance.openstack.common.log as logging from glance.registry.client.v2 import api LOG = logging.getLogger(__name__) def configure(): api.configure_registry_client() def _get_client(func): """Injects a client instance to the each function This decorator creates an instance of the Registry client and passes it as an argument to each function in this API. """ @functools.wraps(func) def wrapper(context, *args, **kwargs): client = api.get_registry_client(context) return func(client, *args, **kwargs) return wrapper @_get_client def image_create(client, values): """Create an image from the values dictionary.""" return client.image_create(values=values) @_get_client def image_update(client, image_id, values, purge_props=False, from_state=None): """ Set the given properties on an image and update it. :raises NotFound if image does not exist. """ return client.image_update(values=values, image_id=image_id, purge_props=purge_props, from_state=from_state) @_get_client def image_destroy(client, image_id): """Destroy the image or raise if it does not exist.""" return client.image_destroy(image_id=image_id) @_get_client def image_get(client, image_id, force_show_deleted=False): return client.image_get(image_id=image_id, force_show_deleted=force_show_deleted) def is_image_visible(context, image, status=None): """Return True if the image is visible in this context.""" # Is admin == image visible if context.is_admin: return True # No owner == image visible if image['owner'] is None: return True # Image is_public == image visible if image['is_public']: return True # Perform tests based on whether we have an owner if context.owner is not None: if context.owner == image['owner']: return True # Figure out if this image is shared with that tenant members = image_member_find(context, image_id=image['id'], member=context.owner, status=status) if members: return True # Private image return False @_get_client def image_get_all(client, filters=None, marker=None, limit=None, sort_key='created_at', sort_dir='desc', member_status='accepted', is_public=None, admin_as_user=False): """ Get all images that match zero or more filters. :param filters: dict of filter keys and values. If a 'properties' key is present, it is treated as a dict of key/value filters on the image properties attribute :param marker: image id after which to start page :param limit: maximum number of images to return :param sort_key: image attribute by which results should be sorted :param sort_dir: direction in which results should be sorted (asc, desc) :param member_status: only return shared images that have this membership status :param is_public: If true, return only public images. If false, return only private and shared images. :param admin_as_user: For backwards compatibility. If true, then return to an admin the equivalent set of images which it would see if it were a regular user """ return client.image_get_all(filters=filters, marker=marker, limit=limit, sort_key=sort_key, sort_dir=sort_dir, member_status=member_status, is_public=is_public, admin_as_user=admin_as_user) @_get_client def image_property_create(client, values, session=None): """Create an ImageProperty object""" return client.image_property_create(values=values) @_get_client def image_property_delete(client, prop_ref, image_ref, session=None): """ Used internally by _image_property_create and image_property_update """ return client.image_property_delete(prop_ref=prop_ref, image_ref=image_ref) @_get_client def image_member_create(client, values, session=None): """Create an ImageMember object""" return client.image_member_create(values=values) @_get_client def image_member_update(client, memb_id, values): """Update an ImageMember object""" return client.image_member_update(memb_id=memb_id, values=values) @_get_client def image_member_delete(client, memb_id, session=None): """Delete an ImageMember object""" client.image_member_delete(memb_id=memb_id) @_get_client def image_member_find(client, image_id=None, member=None, status=None): """Find all members that meet the given criteria :param image_id: identifier of image entity :param member: tenant to which membership has been granted """ return client.image_member_find(image_id=image_id, member=member, status=status) @_get_client def image_member_count(client, image_id): """Return the number of image members for this image :param image_id: identifier of image entity """ return client.image_member_count(image_id=image_id) @_get_client def image_tag_set_all(client, image_id, tags): client.image_tag_set_all(image_id=image_id, tags=tags) @_get_client def image_tag_create(client, image_id, value, session=None): """Create an image tag.""" return client.image_tag_create(image_id=image_id, value=value) @_get_client def image_tag_delete(client, image_id, value, session=None): """Delete an image tag.""" client.image_tag_delete(image_id=image_id, value=value) @_get_client def image_tag_get_all(client, image_id, session=None): """Get a list of tags for a specific image.""" return client.image_tag_get_all(image_id=image_id) @_get_client def user_get_storage_usage(client, owner_id, image_id=None, session=None): return client.user_get_storage_usage(owner_id=owner_id, image_id=image_id) glance-2014.1/glance/db/registry/__init__.py0000664000175400017540000000000012323736226021763 0ustar jenkinsjenkins00000000000000glance-2014.1/glance/db/__init__.py0000664000175400017540000003560112323736230020125 0ustar jenkinsjenkins00000000000000# Copyright 2010 United States Government as represented by the # Administrator of the National Aeronautics and Space Administration. # Copyright 2010-2012 OpenStack Foundation # Copyright 2013 IBM Corp. # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from oslo.config import cfg from glance.common import crypt from glance.common import exception from glance.common import location_strategy import glance.domain import glance.domain.proxy from glance.openstack.common import importutils CONF = cfg.CONF CONF.import_opt('metadata_encryption_key', 'glance.common.config') def get_api(): api = importutils.import_module(CONF.data_api) if hasattr(api, 'configure'): api.configure() return api def unwrap(db_api): return db_api # attributes common to all models BASE_MODEL_ATTRS = set(['id', 'created_at', 'updated_at', 'deleted_at', 'deleted']) IMAGE_ATTRS = BASE_MODEL_ATTRS | set(['name', 'status', 'size', 'virtual_size', 'disk_format', 'container_format', 'min_disk', 'min_ram', 'is_public', 'locations', 'checksum', 'owner', 'protected']) class ImageRepo(object): def __init__(self, context, db_api): self.context = context self.db_api = db_api def get(self, image_id): try: db_api_image = dict(self.db_api.image_get(self.context, image_id)) assert not db_api_image['deleted'] except (exception.NotFound, exception.Forbidden, AssertionError): msg = _("No image found with ID %s") % image_id raise exception.NotFound(msg) tags = self.db_api.image_tag_get_all(self.context, image_id) image = self._format_image_from_db(db_api_image, tags) return ImageProxy(image, self.context, self.db_api) def list(self, marker=None, limit=None, sort_key='created_at', sort_dir='desc', filters=None, member_status='accepted'): db_api_images = self.db_api.image_get_all( self.context, filters=filters, marker=marker, limit=limit, sort_key=sort_key, sort_dir=sort_dir, member_status=member_status) images = [] for db_api_image in db_api_images: tags = self.db_api.image_tag_get_all(self.context, db_api_image['id']) image = self._format_image_from_db(dict(db_api_image), tags) images.append(image) return images def _format_image_from_db(self, db_image, db_tags): visibility = 'public' if db_image['is_public'] else 'private' properties = {} for prop in db_image.pop('properties'): # NOTE(markwash) db api requires us to filter deleted if not prop['deleted']: properties[prop['name']] = prop['value'] locations = db_image['locations'] if CONF.metadata_encryption_key: key = CONF.metadata_encryption_key ld = [] for l in locations: url = crypt.urlsafe_decrypt(key, l['url']) ld.append({'url': url, 'metadata': l['metadata']}) locations = ld return glance.domain.Image( image_id=db_image['id'], name=db_image['name'], status=db_image['status'], created_at=db_image['created_at'], updated_at=db_image['updated_at'], visibility=visibility, min_disk=db_image['min_disk'], min_ram=db_image['min_ram'], protected=db_image['protected'], locations=location_strategy.get_ordered_locations(locations), checksum=db_image['checksum'], owner=db_image['owner'], disk_format=db_image['disk_format'], container_format=db_image['container_format'], size=db_image['size'], virtual_size=db_image['virtual_size'], extra_properties=properties, tags=db_tags ) def _format_image_to_db(self, image): locations = image.locations if CONF.metadata_encryption_key: key = CONF.metadata_encryption_key ld = [] for l in locations: url = crypt.urlsafe_encrypt(key, l['url']) ld.append({'url': url, 'metadata': l['metadata']}) locations = ld return { 'id': image.image_id, 'name': image.name, 'status': image.status, 'created_at': image.created_at, 'min_disk': image.min_disk, 'min_ram': image.min_ram, 'protected': image.protected, 'locations': locations, 'checksum': image.checksum, 'owner': image.owner, 'disk_format': image.disk_format, 'container_format': image.container_format, 'size': image.size, 'virtual_size': image.virtual_size, 'is_public': image.visibility == 'public', 'properties': dict(image.extra_properties), } def add(self, image): image_values = self._format_image_to_db(image) # the updated_at value is not set in the _format_image_to_db # function since it is specific to image create image_values['updated_at'] = image.updated_at new_values = self.db_api.image_create(self.context, image_values) self.db_api.image_tag_set_all(self.context, image.image_id, image.tags) image.created_at = new_values['created_at'] image.updated_at = new_values['updated_at'] def save(self, image): image_values = self._format_image_to_db(image) try: new_values = self.db_api.image_update(self.context, image.image_id, image_values, purge_props=True) except (exception.NotFound, exception.Forbidden): msg = _("No image found with ID %s") % image.image_id raise exception.NotFound(msg) self.db_api.image_tag_set_all(self.context, image.image_id, image.tags) image.updated_at = new_values['updated_at'] def remove(self, image): image_values = self._format_image_to_db(image) try: self.db_api.image_update(self.context, image.image_id, image_values, purge_props=True) except (exception.NotFound, exception.Forbidden): msg = _("No image found with ID %s") % image.image_id raise exception.NotFound(msg) # NOTE(markwash): don't update tags? new_values = self.db_api.image_destroy(self.context, image.image_id) image.updated_at = new_values['updated_at'] class ImageProxy(glance.domain.proxy.Image): def __init__(self, image, context, db_api): self.context = context self.db_api = db_api self.image = image super(ImageProxy, self).__init__(image) def get_member_repo(self): member_repo = ImageMemberRepo(self.context, self.db_api, self.image) return member_repo class ImageMemberRepo(object): def __init__(self, context, db_api, image): self.context = context self.db_api = db_api self.image = image def _format_image_member_from_db(self, db_image_member): return glance.domain.ImageMembership( id=db_image_member['id'], image_id=db_image_member['image_id'], member_id=db_image_member['member'], status=db_image_member['status'], created_at=db_image_member['created_at'], updated_at=db_image_member['updated_at'] ) def _format_image_member_to_db(self, image_member): image_member = {'image_id': self.image.image_id, 'member': image_member.member_id, 'status': image_member.status, 'created_at': image_member.created_at} return image_member def list(self): db_members = self.db_api.image_member_find( self.context, image_id=self.image.image_id) image_members = [] for db_member in db_members: image_members.append(self._format_image_member_from_db(db_member)) return image_members def add(self, image_member): try: self.get(image_member.member_id) except exception.NotFound: pass else: msg = _('The target member %(member_id)s is already ' 'associated with image %(image_id)s.') % { 'member_id': image_member.member_id, 'image_id': self.image.image_id} raise exception.Duplicate(msg) image_member_values = self._format_image_member_to_db(image_member) new_values = self.db_api.image_member_create(self.context, image_member_values) image_member.created_at = new_values['created_at'] image_member.updated_at = new_values['updated_at'] image_member.id = new_values['id'] def remove(self, image_member): try: self.db_api.image_member_delete(self.context, image_member.id) except (exception.NotFound, exception.Forbidden): msg = _("The specified member %s could not be found") raise exception.NotFound(msg % image_member.id) def save(self, image_member): image_member_values = self._format_image_member_to_db(image_member) try: new_values = self.db_api.image_member_update(self.context, image_member.id, image_member_values) except (exception.NotFound, exception.Forbidden): raise exception.NotFound() image_member.updated_at = new_values['updated_at'] def get(self, member_id): try: db_api_image_member = self.db_api.image_member_find( self.context, self.image.image_id, member_id) if not db_api_image_member: raise exception.NotFound() except (exception.NotFound, exception.Forbidden): raise exception.NotFound() image_member = self._format_image_member_from_db( db_api_image_member[0]) return image_member class TaskRepo(object): def _format_task_from_db(self, db_task): return glance.domain.Task( task_id=db_task['id'], task_type=db_task['type'], status=db_task['status'], owner=db_task['owner'], expires_at=db_task['expires_at'], created_at=db_task['created_at'], updated_at=db_task['updated_at'], ) def _format_task_details_from_db(self, db_task): return glance.domain.TaskDetails( task_id=db_task['id'], task_input=db_task['input'], result=db_task['result'], message=db_task['message'], ) def _format_task_to_db(self, task, task_details=None): task = {'id': task.task_id, 'type': task.type, 'status': task.status, 'input': None, 'result': None, 'owner': task.owner, 'message': None, 'expires_at': task.expires_at, 'created_at': task.created_at, 'updated_at': task.updated_at} if task_details is not None: task.update({ 'input': task_details.input, 'result': task_details.result, 'message': task_details.message, }) return task def __init__(self, context, db_api): self.context = context self.db_api = db_api def get_task_and_details(self, task_id): try: db_api_task = self.db_api.task_get(self.context, task_id) except (exception.NotFound, exception.Forbidden): msg = _('Could not find task %s') % task_id raise exception.NotFound(msg) return (self._format_task_from_db(db_api_task), self._format_task_details_from_db(db_api_task)) def list_tasks(self, marker=None, limit=None, sort_key='created_at', sort_dir='desc', filters=None): db_api_tasks = self.db_api.task_get_all(self.context, filters=filters, marker=marker, limit=limit, sort_key=sort_key, sort_dir=sort_dir) return [self._format_task_from_db(task) for task in db_api_tasks] def save(self, task, task_details=None): task_values = self._format_task_to_db(task, task_details) try: updated_values = self.db_api.task_update(self.context, task.task_id, task_values) except (exception.NotFound, exception.Forbidden): msg = _('Could not find task %s') % task.task_id raise exception.NotFound(msg) task.updated_at = updated_values['updated_at'] def add(self, task, task_details=None): task_values = self._format_task_to_db(task, task_details) updated_values = self.db_api.task_create(self.context, task_values) task.created_at = updated_values['created_at'] task.updated_at = updated_values['updated_at'] def remove(self, task): task_values = self._format_task_to_db(task) try: self.db_api.task_update(self.context, task.task_id, task_values) updated_values = self.db_api.task_delete(self.context, task.task_id) except (exception.NotFound, exception.Forbidden): msg = _('Could not find task %s') % task.task_id raise exception.NotFound(msg) task.updated_at = updated_values['updated_at'] task.deleted_at = updated_values['deleted_at'] glance-2014.1/glance/__init__.py0000664000175400017540000000000012323736226017526 0ustar jenkinsjenkins00000000000000glance-2014.1/MANIFEST.in0000664000175400017540000000102112323736226015726 0ustar jenkinsjenkins00000000000000include run_tests.sh ChangeLog include README.rst builddeb.sh include MANIFEST.in pylintrc include AUTHORS include run_tests.py include HACKING.rst include LICENSE include ChangeLog include babel.cfg tox.ini include openstack-common.conf include glance/openstack/common/README include glance/db/sqlalchemy/migrate_repo/README include glance/db/sqlalchemy/migrate_repo/migrate.cfg include glance/db/sqlalchemy/migrate_repo/versions/*.sql graft doc graft etc graft glance/locale graft glance/tests graft tools global-exclude *.pyc glance-2014.1/run_tests.sh0000775000175400017540000001551112323736230016561 0ustar jenkinsjenkins00000000000000#!/bin/bash set -eu function usage { echo "Usage: $0 [OPTION]..." echo "Run Glance's test suite(s)" echo "" echo " -V, --virtual-env Always use virtualenv. Install automatically if not present" echo " -N, --no-virtual-env Don't use virtualenv. Run tests in local environment" echo " -s, --no-site-packages Isolate the virtualenv from the global Python environment" echo " -f, --force Force a clean re-build of the virtual environment. Useful when dependencies have been added." echo " -u, --update Update the virtual environment with any newer package versions" echo " -p, --pep8 Just run PEP8 and HACKING compliance check" echo " -P, --no-pep8 Don't run static code checks" echo " -c, --coverage Generate coverage report" echo " -d, --debug Run tests with testtools instead of testr. This allows you to use the debugger." echo " -h, --help Print this usage message" echo " --virtual-env-path Location of the virtualenv directory" echo " Default: \$(pwd)" echo " --virtual-env-name Name of the virtualenv directory" echo " Default: .venv" echo " --tools-path Location of the tools directory" echo " Default: \$(pwd)" echo " --concurrency How many processes to use when running the tests. A value of 0 autodetects concurrency from your CPU count" echo " Default: 1" echo "" echo "Note: with no options specified, the script will try to run the tests in a virtual environment," echo " If no virtualenv is found, the script will ask if you would like to create one. If you " echo " prefer to run tests NOT in a virtual environment, simply pass the -N option." exit } function process_options { i=1 while [ $i -le $# ]; do case "${!i}" in -h|--help) usage;; -V|--virtual-env) always_venv=1; never_venv=0;; -N|--no-virtual-env) always_venv=0; never_venv=1;; -s|--no-site-packages) no_site_packages=1;; -f|--force) force=1;; -u|--update) update=1;; -p|--pep8) just_pep8=1;; -P|--no-pep8) no_pep8=1;; -c|--coverage) coverage=1;; -d|--debug) debug=1;; --virtual-env-path) (( i++ )) venv_path=${!i} ;; --virtual-env-name) (( i++ )) venv_dir=${!i} ;; --tools-path) (( i++ )) tools_path=${!i} ;; --concurrency) (( i++ )) concurrency=${!i} ;; -*) testropts="$testropts ${!i}";; *) testrargs="$testrargs ${!i}" esac (( i++ )) done } tool_path=${tools_path:-$(pwd)} venv_path=${venv_path:-$(pwd)} venv_dir=${venv_name:-.venv} with_venv=tools/with_venv.sh always_venv=0 never_venv=0 force=0 no_site_packages=0 installvenvopts= testrargs= testropts= wrapper="" just_pep8=0 no_pep8=0 coverage=0 debug=0 update=0 concurrency=1 LANG=en_US.UTF-8 LANGUAGE=en_US:en LC_ALL=C process_options $@ # Make our paths available to other scripts we call export venv_path export venv_dir export venv_name export tools_dir export venv=${venv_path}/${venv_dir} if [ $no_site_packages -eq 1 ]; then installvenvopts="--no-site-packages" fi function run_tests { # Cleanup *pyc ${wrapper} find . -type f -name "*.pyc" -delete if [ $debug -eq 1 ]; then if [ "$testropts" = "" ] && [ "$testrargs" = "" ]; then # Default to running all tests if specific test is not # provided. testrargs="discover ./glance/tests" fi ${wrapper} python -m testtools.run $testropts $testrargs # Short circuit because all of the testr and coverage stuff # below does not make sense when running testtools.run for # debugging purposes. return $? fi if [ $coverage -eq 1 ]; then TESTRTESTS="$TESTRTESTS --coverage" else TESTRTESTS="$TESTRTESTS" fi # Just run the test suites in current environment set +e testrargs=`echo "$testrargs" | sed -e's/^\s*\(.*\)\s*$/\1/'` TESTRTESTS="$TESTRTESTS --testr-args='--subunit --concurrency $concurrency $testropts $testrargs'" if [ setup.cfg -nt glance.egg-info/entry_points.txt ] then ${wrapper} python setup.py egg_info fi echo "Running \`${wrapper} $TESTRTESTS\`" if ${wrapper} which subunit-2to1 2>&1 > /dev/null then # subunit-2to1 is present, testr subunit stream should be in version 2 # format. Convert to version one before colorizing. bash -c "${wrapper} $TESTRTESTS | ${wrapper} subunit-2to1 | ${wrapper} tools/colorizer.py" else bash -c "${wrapper} $TESTRTESTS | ${wrapper} tools/colorizer.py" fi RESULT=$? set -e copy_subunit_log if [ $coverage -eq 1 ]; then echo "Generating coverage report in covhtml/" # Don't compute coverage for common code, which is tested elsewhere ${wrapper} coverage combine ${wrapper} coverage html --include='glance/*' --omit='glance/openstack/common/*' -d covhtml -i fi return $RESULT } function copy_subunit_log { LOGNAME=`cat .testrepository/next-stream` LOGNAME=$(($LOGNAME - 1)) LOGNAME=".testrepository/${LOGNAME}" cp $LOGNAME subunit.log } function run_pep8 { echo "Running flake8 ..." if [ $never_venv -eq 1 ]; then echo "**WARNING**:" echo "Running flake8 without virtual env may miss OpenStack HACKING detection" fi bash -c "${wrapper} flake8" } TESTRTESTS="python -m glance.openstack.common.lockutils python setup.py testr" if [ $never_venv -eq 0 ] then # Remove the virtual environment if --force used if [ $force -eq 1 ]; then echo "Cleaning virtualenv..." rm -rf ${venv} fi if [ $update -eq 1 ]; then echo "Updating virtualenv..." python tools/install_venv.py $installvenvopts fi if [ -e ${venv} ]; then wrapper="${with_venv}" else if [ $always_venv -eq 1 ]; then # Automatically install the virtualenv python tools/install_venv.py $installvenvopts wrapper="${with_venv}" else echo -e "No virtual environment found...create one? (Y/n) \c" read use_ve if [ "x$use_ve" = "xY" -o "x$use_ve" = "x" -o "x$use_ve" = "xy" ]; then # Install the virtualenv and run the test suite in it python tools/install_venv.py $installvenvopts wrapper=${with_venv} fi fi fi fi # Delete old coverage data from previous runs if [ $coverage -eq 1 ]; then ${wrapper} coverage erase fi if [ $just_pep8 -eq 1 ]; then run_pep8 exit fi run_tests # NOTE(sirp): we only want to run pep8 when we're running the full-test suite, # not when we're running tests individually. To handle this, we need to # distinguish between options (testropts), which begin with a '-', and # arguments (testrargs). if [ -z "$testrargs" ]; then if [ $no_pep8 -eq 0 ]; then run_pep8 fi fi glance-2014.1/AUTHORS0000664000175400017540000000024612323736427015253 0ustar jenkinsjenkins00000000000000 Fei Long Wang Hirofumi Ichihara Nikhil Komawar Zhi Yan Liu glance-2014.1/tox.ini0000664000175400017540000000233212323736230015504 0ustar jenkinsjenkins00000000000000[tox] minversion = 1.6 envlist = py26,py27,py33,pep8 skipsdist = True [testenv] setenv = VIRTUAL_ENV={envdir} usedevelop = True install_command = pip install --allow-all-external --allow-insecure netaddr -U {opts} {packages} deps = -r{toxinidir}/requirements.txt -r{toxinidir}/test-requirements.txt commands = python -m glance.openstack.common.lockutils python setup.py test --slowest \ --testr-args='--concurrency 1 {posargs}' [tox:jenkins] downloadcache = ~/cache/pip [testenv:pep8] commands = flake8 {posargs} [testenv:cover] setenv = VIRTUAL_ENV={envdir} commands = python setup.py testr --coverage --testr-args='^(?!.*test.*coverage).*$' [testenv:venv] commands = {posargs} [flake8] # TODO(dmllr): Analyze or fix the warnings blacklisted below # E711 comparison to None should be 'if cond is not None:' # E712 comparison to True should be 'if cond is True:' or 'if cond:' # F821 undefined name 'name' # H302 import only modules # H304 no relative imports # H402 one line docstring needs punctuation. # H404 multi line docstring should start with a summary ignore = E711,E712,F821,H302,H304,H402,H404 builtins = _ exclude = .venv,.git,.tox,dist,doc,etc,*glance/locale*,*openstack/common*,*lib/python*,*egg,build